locked
How to chain error handlers?

    Question

  • Given this code:

    myFuncAsync = function() {
    someFuncAsync().then(function() { return _getMigrationInfoAsync(db); }).then(function(info) { assert(info.version === data.version, "Database version '" + info.version + "' after migration is wrong. Expected it to be " + data.version); return _enableForeignKeySupportAsync(true, db); }, function(error) { });
    }


    The assert function throws an exception, which is not catched by the error handler given. I had to insert an empty success handler after the last then handler to have a global error handler. How are error handlers supposed to be chained within an Async function?

    Monday, February 11, 2013 4:35 PM

Answers

  • In that case you could either have a common function handle your errors in the .done function, or you could chain in another .then function like below:

    myFuncAsync = function() {
      someFuncAsync().then(function() {
        return _getMigrationInfoAsync(db);
      }).then(function(info) {
        assert(info.version === data.version, "Database version '" + info.version + "' after migration is wrong. Expected it to be " + data.version);
        return _enableForeignKeySupportAsync(true, db);
      }, function(error) {
      }).then(function(e) {
        return WinJS.Promise.wrap(e);
      },
      function handleError(ex) {
        // handle the error
      });
    }
    The key here is to note that I wrapped the return value from the previous step into a promise. This allows us to handle the error from the previous result, but also still pass out the value as a promise.


    • Edited by got.dibbs Tuesday, February 12, 2013 1:49 PM
    • Proposed as answer by got.dibbs Wednesday, February 13, 2013 6:59 PM
    • Marked as answer by Song Tian Monday, February 18, 2013 5:41 AM
    Tuesday, February 12, 2013 1:48 PM

All replies

  • You just need to call .done() on your promise. This will have an error handler that can take errors from your .then()'s success handler.

    You could also switch from using .then() to using .done(). This would have the same net effect, except it would ensure that if an error is encountered in your success handler for .done() that it is bubbled up.

    You should pretty much always call .done by the way, otherwise you'll encounter issues with errors like this being swallowed up frequently.

    Monday, February 11, 2013 5:23 PM
  • Calling done won't help in that scenario, cause "done" calls cannot be changed. See my code example "myFuncAsync" is supposed to return a promise. Calling done() will return a value, not a promise. So the caller of myFuncAsync could not chain it.

    I had several times that calling done broke the promise chain and lead to totally unexpected effects.

    Monday, February 11, 2013 6:54 PM
  • You can't call .done() on myFuncAsync? That is where I was thinking you would. You should be able to catch the error then.

    I understand you want myFuncAsync to return a promise, but in order to catch that error, it looks like either you need to call .done after calling myFuncAsync. Is that not possible?

    Monday, February 11, 2013 7:09 PM
  • Yes, sure I could do the error handling outside the function itself. However since I have 4 places that call myFuncAsync, each of those callers would have to provide the error handler. I would have liked to have the error handler right inside myFuncAsync as it will also terminate the app after the displaying the serious error.
    Tuesday, February 12, 2013 9:01 AM
  • In that case you could either have a common function handle your errors in the .done function, or you could chain in another .then function like below:

    myFuncAsync = function() {
      someFuncAsync().then(function() {
        return _getMigrationInfoAsync(db);
      }).then(function(info) {
        assert(info.version === data.version, "Database version '" + info.version + "' after migration is wrong. Expected it to be " + data.version);
        return _enableForeignKeySupportAsync(true, db);
      }, function(error) {
      }).then(function(e) {
        return WinJS.Promise.wrap(e);
      },
      function handleError(ex) {
        // handle the error
      });
    }
    The key here is to note that I wrapped the return value from the previous step into a promise. This allows us to handle the error from the previous result, but also still pass out the value as a promise.


    • Edited by got.dibbs Tuesday, February 12, 2013 1:49 PM
    • Proposed as answer by got.dibbs Wednesday, February 13, 2013 6:59 PM
    • Marked as answer by Song Tian Monday, February 18, 2013 5:41 AM
    Tuesday, February 12, 2013 1:48 PM