deftjs / DeftJS

Extensions for Large-Scale Sencha Touch and Ext JS Applications
http://deftjs.org/
MIT License
285 stars 56 forks source link

Promises catching errors happening in the success method #139

Closed Sighter closed 9 years ago

Sighter commented 9 years ago

Given the following code snippet:

somePromise.then({
    success: function(result) {
        me.fireEvent('authpassed', false);
        me.authPassed(false);
    },
    failure: function(response) {
        ...
    }
}).done();

If inside the "authPassed"-method an exception is thrown, then it gets rethrown via the deftjs handler which actually looses the stacktrace and chromium debugger integration. This behavior is fine while the promise is pending, but i would be cool if this doesn't happen in the success method.

My workaround at the moment is:

somePromise.then({
    success: function(result) {
        Ext.defer(me.fireEvent, 1, me, ['authpassed', false]);
        Ext.defer(me.authPassed, 1, me, [false]);
    },
    failure: function(response) {
        ...
    }
}).done();

This delays the call of the "authpassed"-method to the next turn of the js-event-loop (I think :) Then the exception gets thrown normally with stacktrace.

P.S.: Thank you for this great framework guys which makes ExtJs really usefull for normal sized applications (No Buzzwords here :))

johnyanarella commented 9 years ago

The thing about Promises is that when you call .then() it returns a new Promise of the value as transformed by the success or failure handlers.

This allows the failure handler to implement recovery logic by returning a value that will be propagated as success in the new Promise... and it also allows the success handler to detect and throw errors that will be propagated as a failure in the new Promise.

So, we can't just throw the exceptions from the success handler and still be Promises/A+ specification compliant.

The .done() helper helps address situations like yours where an exception is being swallowed and you explicitly want it to surface, but we're at the mercy of the browser to retain the error's stacktrace when it is rethrown.

It turns out that Chrome does retain the original error's stacktrace, but the debugging tools will show the current stacktrace instead of the original error's stacktrace. (And I suppose that makes some sense - it would make the rethrowing logic pretty hard to debug if it didn't.)

The next time you find yourself in the Chrome/Chromium debugger looking at an error that was rethrown by Deft JS, just type:

error.stack

in the console, and you'll get the original stacktrace.