I'm having an issue on JBoss (6.4.14 GA) running jQuery 3.1.1 (or 3.2.1). As soon as a page loads and the documet.ready function executes I get the following error:
jquery.js:formatted:8142 Uncaught TypeError: aj.then(...).catching is not a function
at bw.fn.init.bw.fn.ready (jquery.js:formatted:8142)
at srs.js:1
The jQuery code throwing this error is:
var readyList = jQuery.Deferred();
jQuery.fn.ready = function( fn ) {
readyList
.then( fn )
// Wrap jQuery.readyException in a function so that the lookup
// happens at the time of error handling instead of callback
// registration.
.catching( function( error ) {
jQuery.readyException( error );
} );
return this;
};
I do not get this error when running my application on Tomcat 7.
I've been researching this error for several days and have been unable to find any references to this specific error (catching is not a function), so looking for some help in determining the cause of this error.
Thanks in advance!
catching is not a method of jquery's deferred, you are maybe looking for catch.
For debugging purpose, you can list properties of an object using Object.getOwnPropertyNames and see which one they have. In your case, executing the code below would have helped you find the error:
var debugValue = aj.then(bS)
console.log(Object.getOwnPropertyNames(debugValue))
Related
I'm just curious,
This...
let s = { f: window.fetch };
s.f("https://www.google.com");
fails with
Failed to execute 'fetch' on 'Window': Illegal invocation
While this works...
let s = { f: window.fetch.bind(window) };
s.f("https://www.google.com");
How does the latter fix the issue? Is there any theory behind why it works that way?
For some internal purpose, the fetch function must have this be the same as window. When you create your own object and just assign the fetch function as one of its properties, the fetch function has no access to the window object as this.
The fetch specification describes things the window might be used for. You might be able to make your original code work by setting no-window, but I have not tested that.
So as the title states I would like to be able to intercept all errors that occur on the page. So starting off with the simplest way:
Add an error event listener to window and store the errors as they occur
The problem with this approach is that if the code that is causing the error is wrapped in a try catch block, the error listener never gets triggered.
A partial solution to this issue is to override the Error constructor so that any time code such as throw new Error() is called we can intercept it using our override. This approach works very nicely for user generated errors, this doesn't work for errors that originate in the browser. For example:
const a = ()=> {
const b = {};
console.log(b.c.d) // Uncaught TypeError: Cannot read property 'c' of undefined
}
try {
a()
} catch(err) {
console.log(err)
}
I would like to be able to detect that a TypeError has been thrown. Overriding the TypeError constructor does not work in this case.
Any ideas?
EDIT: The point is to be able to intercept errors that 3rd party scripts wrap with a try catch
I have been trying to create JavaScript that includes functions for managing an IndexedDB database that acts as a filesystem; the segment of code below helps protect the database from being modified in unauthorized ways by other client-side scripts, but an uncaught "TypeError: Illegal invocation" exception is thrown on line 16.
$(document).ready(function(){
var db;
var proxiedDBOpen = indexedDB.open.bind(window);
indexedDB.open = function(name, version) {
if(name === 'MyTestDatabase')
{
console.error('Security error: Unauthorized filesystem access.');
return;
}
else
{
return proxiedDBOpen.apply(window, arguments);
}
}
var request = proxiedDBOpen('MyTestDatabase', 4); // Uncaught TypeError: Illegal invocation
// Database management code follows (uses jQuery)...
});
After reading other posts, I tried making sure this was set to window in the scope of the call to proxiedDBOpen (Function.prototype.bind is called on line 3 in an attempt to do this), but this did not seem to help; I also tried var request = function(name, version) {return proxiedDBOpen.apply(this, arguments);}('MyTestDatabase', 4);, which causes the same exception at the call to proxiedDBOpen.apply.
#levi's suggestion solved my problem (indexedDB.open expects this to be indexedDB in its context).
To make debugging easier, I'm capturing all of the console logs in Chrome so that users who submit a feedback entry will also submit all of the logs to our server. When someone encounters a problem in production, I can first and foremost get them back to work so that I can then sit down and more thoroughly go through all of the logs to determine the root cause of whatever issue the user encountered in production.
The technique I use to capture the logs involves overriding console.log so that all text entered in the first argument gets stored in an array while simultaneously invoking the legacy function so that I can still see the logs in the console too.
The problem is when there's the occasional uncaught exception. These aren't included in the uploaded logs, so it's not always clear what caused the problem. So I tried overriding ReferenceError by writing a JavaScript function that takes a function as an argument, then returns a new function that does stuff with it, like storing data in a variable, and then invoking the legacy function as the last step:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
To test the overrideException function, I ran the following code on the console:
ReferenceError = overrideException(ReferenceError);
Afterwards, I tested the returned function, the new ReferenceError, by manually throwing a ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
The resulting output on the console is:
ReferenceError: YES!! IT WORKS! HAHAHA!
And checking the global variable output from the overrideException function shows that it did indeed run:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
Now, here's where things start to fall apart. In our code, we're not going to know when an uncaught exception occurs, so I tested it by attempting to run a function that doesn't exist:
ttt();
Which results in:
ReferenceError: ttt is not defined
However, unlike the case where we explicitly throw an error, in this case, the function doesn't fire, and we're left with only the legacy functionality. The contents of the variable output is the same as in the first test.
So the question seems to be this: How do we override the ReferenceError functionality that the JavaScript engine uses to throw errors so that it's the same one we use when we throw a ReferenceError?
Keep in mind that my problem is limited only to Chrome at this time; I'm building a Chrome Packaged app.
I have done quite a bit of research for the same reason: I wanted to log errors and report them.
"Overriding" a native type (whether ReferenceError, String, or Array) is not possible.
Chrome binds these before any Javascript is run, so redefining window.ReferenceError has no effect.
You can extend ReferenceError with something like ReferenceError.prototype.extension = function() { return 0; }, or even override toString (for consistency, try it on the page, not the Dev Tools).
That doesn't help you much.
But not to worry....
(1) Use window.onerror to get file name, 1-indexed line number, and 0-indexed position of uncaught errors, as well as the error itself.
var errorData = [];
onerror = function(message, file, line, position, error) {
errorData.push({message:message, file:file, line:line, position:position, error:error});
};
See the fiddle for an example. Since the OP was Chrome-specific, this has only been tested to work in Chrome.
(2) Because of improvements to (1), this is no longer necessary, but I leave this second technique here for completeness, and since onerror is not guaranteed to work for all errors on all browsers. You will also sometimes see the following:
var errors = [];
function protectedFunction(f) {
return function() {
try {
f.apply(this, arguments);
} catch(e) {
errors.push(e);
throw e;
}
};
}
setTimeout = protectedFunction(setTimeout);
setInterval = protectedFunction(setInterval);
etc...
FYI, all this is very similar to what has been done in the Google Closure Compiler library, in goog.debug, created during Gmail development with the intent of doing exactly this. Of particular interest is goog.debug.ErrorHandler and goog.debug.ErrorReporter.
In under the Week-view, on event mouseOver I receive this error message in firebug:
Error: Syntax error, unrecognized expression: ,
throw new Error( "Syntax error, unrecognized expression: " + msg );
jquery-1.8.3.js (line 4680)
has anyone encountered such a problem, or is there a way to debug to origins of the error?
Thanks in advance
Sincerely
It looks like a selector bug:
$("abc, def, "); // or
$("<div,");
Is not sure.
If you look in the source code for jQuery 1.8.3 you will find these lines around line 4680:
/*LINE: 4679*/ Sizzle.error = function( msg ) {
/*LINE: 4680*/ throw new Error( "Syntax error, unrecognized expression: " + msg );
/*LINE: 4681*/ };
It's hard to debug your code from here but you could try to put arguments.callee.caller right before throw new Error:
Sizzle.error = function( msg ) {
console.log( arguments.callee.caller );
throw new Error( "Syntax error, unrecognized expression: " + msg );
};
That will tell you what function is calling this function. From there you can try to travel up using the same method. At the end you will find your problem.
What is arguments.callee.caller?
arguments is an array like property containing all the arguments parsed to a function:
function a() {}
a(1, 2, 3); // Inside a arguments will be: [1, 2, 3]
arguments have a property called callee this property contains a reference to the function called eg. it self:
function a() {} // arguments.callee === a.
arguments.callee have a non standard (but standard, just not described in ECMA) property called caller this property contains a reference to the function who is calling it on runtime.
function a() {
b()
}
function b() {}; // arguments.callee.caller === a;
a();
And some docs:
arguments
arguments.callee
Function.caller
Do you know about the console-object?
The problem was solved by going away from jQuery-Mobile and back to jQuery-UI only.
FullCalendar doesn't work properly under jQuery-Mobile.
The problem was caused by jQuery-Mobile. FullCalendar could not function properly in jQuery-Mobile environment. After going back to jQuery-UI everything worked fine again.
Thanks for your effort to help