[Noisebridge-discuss] Asynchronous Callbacks and Error Handling

girlgeek girlgeek at wt.net
Sun Mar 30 06:03:12 UTC 2014


Garrett,
Who gave you permission to post interesting and hacker relevant 
information to this board?
Harrumpf!
-Claudia



On 3/30/2014 12:16 AM, Garrett Smith wrote:
> Async callbacks happen outside of the normal event loop.
> http://jsbin.com/laraqozi/1/edit
>
> The call to setTimeout in the try block succeeds without error,
> passing it the function.
>
> Later, when the browser calls the callback that was passed to
> setTimeout, an error is thrown.
>
> Similarly with event handler callbacks that throw errors, either from
> IO or from something as simple as onclick:
>
>    document.addEventListener("click", doSomethingBad, false);
>
> No error is thrown by attaching `doSomethingBad`; the error happens
> when doSomethingBad is triggered later on.
>
> Asynchronous errors are harder to track down because the stack trace
> stops at the browser internal code. The function that called
> setTimeout is not part of the stack trace.
>
> The contrived example is pretty obvious about what it does: throw
> Error("..."). In reality, code that is throwing an error will be more
> complicated and may depend the state of other objects. Conditional
> breakpoints can help.
>
> Async errors can't be caught in a sync try/catch, but can be caught by
> either wrapping the call to the callback in a try/catch and handling
> the error there, or by using a global onerror handler. But global
> onerror won't tell you more than developer tools' stack trace does and
> is only useful for graceful error-handling and reporting in the UI.
>
> Generally, code that calls async callbacks should provide an error
> handler callback. For example in async requests:
>
> makeRequest(url, {success: callback, error: errback});
>
> In runtime script errors:
> //-----------------------------------
> // Deferred Callback Error Handling
> //-----------------------------------
> function deferCallback(f, errback) {
>      var wrapped = asyncCallbackWrapper(f, errback);
>      setTimeout(wrapped, 100);
> }
>
> function asyncCallbackWrapper(f, errback) {
>    return _safeWrap;
>    function _safeWrap() {
>      try {
>        f();
>      } catch(ex) {
>        errback(ex);
>      }
>    }
> }
>
> deferCallback(doSomethingBad, function errback(ex) {
>    alert("doSomethingBad threw: " + ex.name +", " + ex.message);
> });



More information about the Noisebridge-discuss mailing list