acceptable promise pattern for 'LOUD' errors?

前端 未结 2 1324
天命终不由人
天命终不由人 2020-12-11 08:10

I\'m using the RSVP library distributed inside Ember.js and I\'m trying to figure out the correct pattern for reporting fatal errors inside a promise -- particularly I want

相关标签:
2条回答
  • 2020-12-11 08:39

    New answer --

    In this video panel discussion with ember core developers, at one point the developers all share one debugging tip:

    http://www.youtube.com/watch?v=L9OOMygo1HI

    Tom Dale specifically addresses the issue of swallowed exceptions inside promises and recommends use of the new Ember.RSVP.onerror feature for debugging errors inside promises which would have otherwise gone unreported because no rejection handler was attached.

    I think that is the correct answer to my question -- although I don't yet know how to use the RSVP.onerror callback (or in which ember releases its available) ...

    0 讨论(0)
  • 2020-12-11 08:42

    Nice question!

    You could get away with the setTimeout within a dev environment. But for production where you log these errors for reporting for instance, You will want to avoid setTimeout as it's non-deterministic. You could end up seeing errors that aren't really accurate, but occurred due to some order in which the setTimeout fired.

    You can do this by moving your checks to the first then of the promise, and then returning that thenable instead of deferred directly.

    I prefer to use Ember.Deferred instead of Ember.RSVP.Promise. Deferred is a layer over RSVP that has a nicer API. It avoids needing to nest the whole thing inside a callback to Ember.RSVP.Promise. Ember.Deferred provides resolve and reject as methods.

    model: function(params) {
      var promise = Ember.Deferred.create();
      var successCallback = function(resp) {
        promise.resolve(resp);
      };
    
      var errorCallback = function(err) {
        promise.reject(err);
      };
    
      var thenable = promise.then(function(resp) {
        if (resp.isError) {
          throw new Error(resp.errorMessage);
        } else {
          return resp;
        }
      });
    
      // some api that takes a callback
      this.callApi(params, successCallback, errorCallback);
    
      return thenable;
    },
    

    Throwing an error at any point in the promise/API will automatically reject the promise. So you don't need to catch and rethrow anything.

    This allows for 3 different types of responses.

    successCallback with response data.

     successCallback({data: 'foo'});
    

    successCallback with error in response.

     successCallback({isError: true, errorMessage: 'Response data is wrong'});
    

    errorCallback with message.

     errorCallback('Incorrect use of API');
    

    See this jsbin to try this out.

    You could clean this up a bit if the API that you call uses promises instead of callbacks. Then you can just chain the thens.

    0 讨论(0)
提交回复
热议问题