Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deferred: Give better stack diagnostics on exceptions #3113

Closed
wants to merge 2 commits into from

Conversation

dmethvin
Copy link
Member

Summary

Ref gh-2736

The exception stack has the name of the immediately outer function where the
exception occurred, which can be very handy for tracing errors. Since we already
have the exception object we might as well use it.

I was debugging some code that had errors inside a document ready function and this would have been really useful to have.

Checklist

Mark an [x] for completed items, if you're not sure leave them unchecked and we can assist.

Thanks! Bots and humans will be around shortly to check it out.

Ref jquerygh-2736

The exception stack has the name of the immediately outer function where the
exception occurred, which can be very handy for tracing errors. Since we already
have the exception object we might as well use it.
@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @mgol, @gibson042 and @markelog to be potential reviewers

@dmethvin dmethvin added this to the 3.0.0 milestone May 11, 2016
window.console.warn = oldWarn;
done();
} );

defer.resolve();
} );

// Test fails in IE9 but is skipped there because console is not active
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it fail with DevTools open? If so, why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IE9 doesn't have error.stack.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a check for (new Error()).stack here so that the tests work even with IE9 DevTools enabled?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give that a try!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, I just remembered:

Different browsers set this value at different times. For example, Firefox sets it when creating an Error object, while PhantomJS sets it only when throwing the Error, and MSDN docs also seem to match the PhantomJS implementation. -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack

So the test would need to be more elaborate. I think the current check is less likely to skip by accident at least? Everyone but IE9 has a console.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I thought it'd be simpler. 😅 It's OK then.

@mgol
Copy link
Member

mgol commented May 11, 2016

So, the idea is that this stack trace is nowhere near that useful than the original one which would be passed by your jquery-deferred-reporter plugin but it still provides some useful info?

@@ -11,10 +11,10 @@ var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;

jQuery.Deferred.exceptionHook = function( error, stack ) {

// Support: IE 8 - 9 only
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not change this comment. We've decided some time ago to not remove info about workarounds for now non-supported browsers as long as we still need the workaround for other, supported ones.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, for some reason I thought we were doing the opposite.

@mgol
Copy link
Member

mgol commented May 11, 2016

I don't see the name in the stack trace for the handler named barf in Chrome 50, that's what I see:

jQuery.Deferred exception: jQuery.thisDiesToo is not a function TypeError: jQuery.thisDiesToo is not a function
    at Array.barf (<anonymous>:12:9)
    at mightThrow (http://jquery.l/dist/jquery.js:3505:29)
    at process (http://jquery.l/dist/jquery.js:3573:12) undefined

It shows Array.barf which seems weird.

@mgol
Copy link
Member

mgol commented May 11, 2016

Firefox, on the other hand, show just the first error (Chrome shows both, with stack traces with your patch):

TypeError: jQuery.barf is not a function

with no stack trace. I'm doing the testing with this code:

var defer = jQuery.Deferred();

jQuery.when(
    defer.then( function() {
        jQuery.barf();
    } ).then( null, jQuery.noop ),

    defer.then( function() {
        throw new Error( "Make me a sandwich" );
    } ).then( null, jQuery.noop )
).then( function barf( ) {
    jQuery.thisDiesToo();
} );

defer.resolve();

@mgol
Copy link
Member

mgol commented May 11, 2016

Interesting; even with:

jQuery.Deferred.exceptionHook = function( error, stack ) {
    console.log("jQuery.Deferred exception: " + error.message, error.name, error.stack, stack );
};

I see 3 errors in Chrome with this test but only one error message in Firefox and the Firefox one doesn't seem to come from jQuery as it doesn't begin with jQuery.Deferred exception:.

@mgol
Copy link
Member

mgol commented May 11, 2016

It all works fine for me in Firefox beta or newer so perhaps only the current version has problems.

The exceptionHook with stack test also needed to see all args, since the arg
order was changed.

var done = assert.async(),
defer = jQuery.Deferred(),
oldWarn = window.console.warn;

window.console.warn = function( msg ) {
window.console.warn = function() {

// Support: Chrome <=41 only
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've dropped Yandex now, but I guess this is still needed for Android 5.0?

Copy link
Member

@mgol mgol May 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, although technically that shouldn't matter as Android 5.0 has both auto-updatable browser (Chrome) & WebView. It's just that BrowserStack doesn't update Chrome in Android images (I'm not sure if that's even possible in emulators). The solution would be to move to Android 6.0 and drop 5.0 as we're really interested in testing Chrome for Android, not specific Android versions (it used to be different as Android Browser versions were tied to Android versions as is still the case on iOS) but last time I checked local testing didn't work on Android 6.0 on BrowserStack. I'll need to re-check, if it worked now we'd be able to drop these workarounds.

@dmethvin
Copy link
Member Author

Closed by 07c11c0

@dmethvin dmethvin closed this May 12, 2016
@dmethvin dmethvin deleted the better-stack branch May 24, 2016 19:07
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants