acceptable promise pattern for 'LOUD' errors?

前端 未结 2 1333
天命终不由人
天命终不由人 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: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.

提交回复
热议问题