I can't seem to find anything in the Chrome extension documentation about exception handling. All the asynchronous apis makes it very difficult without littering the code with try / catch statements everywhere..
How can I add a global exception handler to my background page that'll allow me to do some resource cleanup in the case of an exception?
You can get the error in the execute script callback with chrome.runtime.lastError:
chrome.tabs.executeScript(tabId, details, function() {
if (chrome.runtime.lastError) {
var errorMsg = chrome.runtime.lastError.message
if (errorMsg == "Cannot access a chrome:// URL") {
// Error handling here
}
}
})
I haven't been able to find a global error handler but I was able to come up with a solution that works just as well.
It does depend on what methods you're calling though. Most of my errors came from calling chrome.tabs.executeScript() on a chrome:// page or a chrome webstore page. The last parameter of this function is a callback that contains a results array. I found that if this was undefined I was getting an error back. This way I was able to set up a simple error handling function to notify the user when there was an error.
chrome.tabs.executeScript(null, {file: '/path/to/file.js'}, function(results) {
if (results === undefined) {
// Fire error handling code
}
});
Again, Idk if this is applicable with the methods that you're calling but I was able to do what I wanted this way.
Related
In file2.js I have:
throw new String("oops");
In file1.js I have:
document.head.appendChild(dynamically_created_file_2_script_element);
How can I catch the string thrown in file2.js?
I have tried:
try {
document.head.appendChild(dynamically_created_file_2_script_element);
}
catch(err) { ... }
to no avail. Also, the onerror event listener on dynamically_created_file_1_script_element is of no use here.
Before appending the script, you can add an error listener to the window.
The error event is fired on a Window object when a resource failed to load or couldn't be used — for example if a script has an execution error.
Inside the handler, you can check which resource resulted in the error by looking at the filename property of the event.
window.addEventListener('error', (errorEvent) => {
if (errorEvent.filename.endsWith('file2.js')) {
console.log('Saw error from file2.js:')
console.log(errorEvent.message);
}
});
document.body.appendChild(document.createElement('script')).src = './file2.js';
Note that this can only work if the script is on a live server, and on the same domain. Due to cross-origin restrictions, in other situations, the only info available will be Script error.
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
When a Uncaught Exception is thrown in some website or web application, an error appears in the Develper tools in each browser
In Electron for instance, if an uncaught exception, the developer can set a listener and do whatever I want with the error message:
process.on('uncaughtException', function (error) {
// Handle the error
}
So, I wonder if there is an easy way to do the same in JavaScript. This could be useful in order to record and store common errors when the users are working, or in order to show what's happening to the user, who can send feedback to the developers.
Something like this could be shown instead
Sometimes, if an error occurs the app become in a unstable state where everything is frozen, and the user do not know why. I think informing about the error is important.
I found this Error JavaScript object. It can be manually thrown, but that can be used only when try and catch are used, and not for the uncaught exceptions, where the developer made some mistakes.
You can handle it as an event listener on window object.
window.onunhandledrejection = event => {
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
};
window.onerror = function(message, source, lineNumber, colno, error) {
console.warn(`UNHANDLED ERROR: ${error.stack}`);
};
Or also like this:
window.addEventListener('error', function(event) { ... })
You can read more about the unhandledrejection event on the MDN web docs here and the onerror event on the docs here
try {
// YOUR CODE GOES HERE
} catch (e) {
if ( e instanceof CustomExceptionError ) {
// ...
} else if ( e instanceof OtherExceptionError ) {
// ...
} else {
// ...
}
//OR CALL THE ALERT BOX OR ANY OTHER UI CHANGE
}
I have a problem that is driving me crazy. I have two event listeners that appear to be identical. The are being called with the same scope but at different times. I have been using chromes debugger tool to step through them. The first one will throw an error
TypeError: Object 1 has no method 'get'
But the second example simple stops executing
el.on("change:one", function() {
debugger;
a = 1;
a.get();
});
el.on("change:two", function() {
debugger;
a = 1;
a.get();
});
I understand that simple asking why is this happening probably needs a detailed explanation of all the libraries being used etc, so my question is:
Is it possible to not display errors thrown by javascript, and how would I be able to detect whether something is overriding the error reporting functionality
NOTE: In both examples I have determined that window.onerror is null
Backbone invokes event handlers synchronously and doesn't catch handler exceptions. So if you had code that looked like:
el.trigger('change:one'); // handler will throw exception
el.trigger('change:two'); // won't execute
The change:two event will never get triggered, resulting in your change:two handler never getting invoked.
I can't find a way to catch the error message under firefox:
window.addEventListener("error", handleException, false);
...
function handleException(e) {
alert(e);
return false;
}
...
<script>
throw new Error('sdasd');
</script>
This enters very well the handleException method however the e parameter is an error event under firefox and I don't know how to get the associated message.
In chrome for instance, I get either the message through e.message because after the error bubbles up to not being caught, there's an automatic error fired at window level (See this fiddle: the final error is "Uncaught") that contains the original error that I raised manually.
So to have the same behaviour under firefox (if you run the fiddle under firefox you'll see that the message is "undefined") I found a workaround consisting in encapsulating an error raising function to setup a manual "last error" architecture:
function err(I_sText) {
g_lastManualError = new Error(I_sText);
throw g_lastManualError; //this variable is global so I can get the message from anywhere
}
So instead of doing throw new Error(..) I only call err(..). That works, at least for user defined exceptions, which are my biggest concern. In my handler handleException I'm consulting the global variable.
Do you know how I could do otherwise? I'm not happy with this solution.
Thank you,
S.
I modified your code a little as a demo:
function handleException(e) {
console.log(e);
alert(e);
return false;
}
window.addEventListener("error", handleException, false);
try {
throw new Error('sdasd');
}
catch (e) {
console.log(e)
}
console.log('after exception 1');
throw new Error('foo');
console.log('after exception 2');
Running this code (in Firebug) showed me this:
Error: sdasd
[Break On This Error]
Filtered chrome url chrome://firebug/content/console/commandLineExposed.js
comman...osed.js (line 175)
<System>
after exception 1
"Error: foo ` throw new Error('foo');` #14"
If you're trying to catch an error, use try {...} catch { ...}. It looks like you're just binding to an error event, so the exception you're throwing will still propagate up to window and tell the JS engine to halt. Run this code in Chrome, you'll see that you never see "after exception 2", but you will see "after exception 1".
The purpose of exceptions (created by throw) is to stop code execution unless there's code made to handle that particular exception. You can see an example on the MDN page for try-catch
Edit: it just occurred to me that you might be trying to catch a jQuery error event. If this is the case, your event binding is correct but you shouldn't be testing it with throw
Edit 2: I should've noticed this sooner, but you're trying to listen for a DOM error event with window.addEventListener. Error events will not break execution. Exceptions do.
Replace your code throw new Error('sdasd'); with this code:
var customEvent = new CustomEvent('error')
window.dispatchEvent(customEvent);
That should solve your problem. I used the MDN page on custom events as a reference.