-
Notifications
You must be signed in to change notification settings - Fork 70
Living with a previously defined onerror-function #43
Comments
Hey @joshuap I just wrote this up quick, can you throw it in Honeybadger and make sure all basic functionality is still in tact? @gaiottino, in your window.onerror functon, you'll have a 4th parameter from TraceKit that is a callback to notifyHandlers or not (see pull request) it'll be like: window.onerror = function(a,b,c, notifyTraceKitHandlers) {
if (???) {
notifyTraceKitHandlers();
}
}; Please fully test and let me know if this all works out for you guys in a few days. For convenience, the fix: devinrhode2@e1c43c5 Last but not least, this needs to be documented before merging to master. cc @occ |
Perhaps a better api would be more like: window.onerror = function(a,b,c) {
...
this.notifyHandlers();
}; The Actually, since the return value of onerror really doesn't play a role in anything anywhere, you could just: window.onerror = function(a,b,c) {
return {notifyTraceKitHandlers: true};
//or
}; I think the The |
@gaiottino and @joshuap, docs on new api here: https://github.com/devinrhode2/TraceKit/blob/patch-5/README.md#existing-windowonerror-function Again, I just wrote this up quickly, so please grab the tracekit.js file here: https://github.com/devinrhode2/TraceKit/blob/patch-5/tracekit.js test it. Let me know how this works for you guys. |
I added a branch with the new tracekit.js: https://github.com/honeybadger-io/honeybadger-js/tree/devinrhode2-patch-5 Our tests are passing. :) I agree that it's best to keep the handler notification logic in tracekit.js. I'm personally not a big fan of using window.onerror for catching errors at all - we disable it by default, as I believe you guys also discourage it? That said, this new API seems like a nice way to filter out certain events from the parent function. @gaiottino can you confirm that this fixes your issue of the dom being replaced after handlers are called? Thanks for the quick turnaround @devinrhode2! |
I'm currently away on holiday this week but will verify and update this thread first thing next week. Thanks for all your input :) |
Just about to test this now. I don't understand why you chose a custom return value instead of relying on the existing definition which only return true or false. https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onerror With your new custom return value, users will have to modify existing onerror-functions to make them compatible with TraceKit/Honeybadger. It also means that the TraceKit onerror-function returns an invalid value when there's an existing function since you just forward the new custom return value. I vote for relying on the existing return value-definition instead of introducing a new way to handle this. |
Do you have any suggestions on what the api would look like? I think the 4th parameter works well in this case.. this.notifyHandlers is interesting, but this is the global object here.. Will do some investigating |
I think the API should just be true or false like it is defined in https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onerror if (_oldOnerrorHandler) {
var _oldOnerrorReturn = _oldOnerrorHandler.apply(this, arguments);
if (!_oldOnerrorReturn || _oldOnerrorReturn != true) {
notifyHandlers(stack, 'from window.onerror');
}
return _oldOnerrorReturn; // preserve any potential return behavior of the old onerror function.
} else {
notifyHandlers(stack, 'from window.onerror');
}
return false; |
Been thinking about this some more and realized that just relying on true/false isn't ideal. Returning true/false should be used as defined so that it's possible to prevent the firing of the default event handler and TraceKit should return this value as defined in the onerror-function. But I do like this bit of code though window.onerror = function(a,b,c, notifyTraceKitHandlers) {
if (???) {
notifyTraceKitHandlers();
}
}; It would give the user complete control of when to notify e.g. Honeybadger but also tell the browser whether to fire the default handler using true or false as return-value. |
@devinrhode2 any update/thoughts? |
Passing the function as a 4th arg is a better api, just have to find a
|
After I wrote this, I realized that, really, the best API of all would be a simple function hanging off the TraceKit namespace. I'm working on re-doing a lot of stuff and should be able to include this easily. For record, I'm leaving my internal monolog coming to this conclusion below. Warning: Please don't waste your time reading all this Ok so now that Chrome introduced new arguments to It would be implemented a little bit like this: window.onerror = function(){
if (this.notifyHandlers) {
this.notifyHandlers();
}
console.log('Still access global properties via this? this.location.href:', this.location.href);
return false; //always let the default event handler fire..
};
notifyHandlers = undefined;
function extendWindow() {
//assert called with 'new'
this.notifyHandlers = function(){console.log('notifyHandlers called');};
}
extendWindow.prototype = window;
console.log('yeah...', onerror.call(new extendWindow()));
console.log('notifyHandlers undefined?', notifyHandlers === undefined); This creates the this.notifyHandlers without polluting global scope, however, I personally prefer passing in the function as the last argument. Instead of if (this.notifyHandlers) this.notifyHandlers(); You would do this: arguments[arguments.length](); Which is more straightforward but less readable. Perhaps the best of all is compensating for Chrome's new 5 argument window.onerror = function(message, lineNo, colNo, something, actualException, notifyTraceKitHandlers) {
}; |
Hi,
I previously reported this to the Honeybadger issue list, but they informed me that the code in question was actually part of your project. So here goes...
I was working on getting Honeybadger integrated in our app and ran into an issue. It's a heavy client-side app and we have our own onerror-function defined. In this function we ignore quite a number of errors which occurs in various libraries (and browser extensions) which doesn't affect our site. When an error we can't recover from occurs we render a failure page.
This is where I found the issue. Notifications weren't being sent to Honeybadger. The reason is because Honeybadger dynamically adds elements to the document in order to perform a crossdomain post, but our failure-page-rendering removed everything from the body before it renders which removes the Honeybadger elements and thus nothing is sent.
The code in question is part of TraceKit and looks like this
I believe there are two issues here. (1) You attempt to notify handlers before the old onerror handler has run (if it exists). (2) TraceKit does not respect the return of the old onerror method. Returning true prevents the firing of the default event handler (i.e. the error has been dealt with), and I feel that this should also be respected by TraceKit.
I'd like to see the code be changed to something similar to
Now TraceKit notifies hanglers after the already defined error handling has been run, and only notifies handlers if the error hasn't already been dealt with.
The text was updated successfully, but these errors were encountered: