首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ember中实现正确的全局HTTP错误处理

如何在ember中实现正确的全局HTTP错误处理
EN

Stack Overflow用户
提问于 2015-08-18 17:29:52
回答 2查看 6.6K关注 0票数 9

我想要的是:在全球范围内处理不同http错误(401,404,500)的错误处理。在何处或何时发生http错误并不重要。

到目前为止,我在应用程序路由中实现了一个错误操作,该操作将在路由的model钩子上的任何适配器错误上调用。效果很好。

当我在其他上下文(如record.save() )中处理记录时,没有涉及到的情况。在这里,我需要单独处理承诺上的错误。

此外,我不仅想要一个默认的错误处理程序,而且更像是一个后备程序。

好的,在讨论太多之前,让我们先来一个我的用例的示例实现。

应用路由

应用程序错误操作应该是默认/回退错误处理程序。

代码语言:javascript
复制
actions: {
  error: function(error) {
    var couldHandleError = false;

    if (error.errors) {
      switch (error.errors[0].status) {
        case '401':
          // User couldn't get authenticated.
          // Redirect handling to login.

          couldHandleError = true;
          break;
        case '404':
        case '500':
          // Something went unexpectedly wrong.
          // Let's show the user a message

          couldHandleError = true;
          break;
      }
    }

    // return true if none of the status code was matching
    return !couldHandleError;
  }
}

某些路由

在这种情况下,调用应用程序错误操作。

代码语言:javascript
复制
model: function() {
  return this.store.findAll('post');
}

某些控制器

在这种情况下,不调用应用程序错误操作。

(我知道,下面的代码可能没有意义,但它只是为了说明我的需求)

代码语言:javascript
复制
this.store.findRecord('post', 123);

其他控制器

在本例中,应用程序错误操作肯定不会被调用,因为我在这里使用了自己的处理程序(catch())。但是,正如您在注释中看到的,我确实希望对除404之外的所有状态代码使用默认处理程序。

代码语言:javascript
复制
this.store.findRecord('post', 123).catch(function(reason) {
  if (reason.errors[0].status === '404') {
    // Do some specific error handling for 404
  } else {
    // At this point I want to call the default error handler
  }
});

那么,是否有一个干净和被认可的方法来实现这一点呢?我希望我能把我的问题告诉你。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-18 18:17:23

您可以尝试对这些事件执行一些操作(在应用程序初始化之前将这些行放在app.js中):

代码语言:javascript
复制
Ember.onerror = function (error) {
  console.log('Ember.onerror handler', error.message);
};

Ember.RSVP.on('error', function (error) {
  console.log('Ember.RSVP error handler', error);
});

Ember.Logger.error = function (message, cause, stack) {
  console.log('Ember.Logger.error handler', message, cause, stack);
};

我是从https://raygun.io/blog/2015/01/javascript-error-handling-ember-js/了解到的,你可以在那里找到一些细节。

票数 7
EN

Stack Overflow用户

发布于 2015-08-20 13:06:06

我想我有我的最后解决方案,我想和你们分享。基本上,我采纳了那些评论我问题的人的想法,并扩展了它们,使它们符合我的需要。

首先,我创建了一个包含主逻辑的混合器。因为我希望它尽可能通用,所以它区分了a)控制器/路由和b) jquery /适配器错误。因此,无论您在哪里调用它,以及您的错误对象是来自jquery请求还是ember适配器,都无关紧要。

代码语言:javascript
复制
import Ember from 'ember';

export default Ember.Mixin.create({

  ajaxError: function(error) {
    if (!error) {
      Ember.Logger.warn('No (valid) error object provided! ajaxError function must be called with the error object as its argument.');
      return;
    }

    // Depending whether the mixin is used in controller or route
    // we need to use different methods.
    var transitionFunc = this.transitionToRoute || this.transitionTo,
        couldHandleError = false;

    switch (this._getStatusCode(error)) {
      case 401:
        transitionFunc.call(this, 'auth.logout');
        couldHandleError = true;
        break;
      case 404:
      case 500:
        // Here we trigger a service to show an server error message.
        // This is just an example and currently not the final implementation.
        // this.get('notificationService').show(); 
        couldHandleError = true;
        break;
    }

    // For all other errors just log them.
    if (!couldHandleError) {
      Ember.Logger.error(error);
    }
  },

  _getStatusCode: function(error) {
    // First check for jQuery error object
    var status = error.status;

    // Check for ember adapter error object if it's not a jquery error
    if (!status && error.errors && error.errors[0].status) {
      status = parseInt(error.errors[0].status);
    }

    return status;
  },

});

接下来,我重新打开了一些类(在app.js中),以使这个功能在全局可用:

代码语言:javascript
复制
import AjaxErrorMixin from 'app/mixins/ajax-error';

Ember.Route.reopen(AjaxErrorMixin);
Ember.Controller.reopen(AjaxErrorMixin);

Ember.Component.reopen({
  _actions: {
    // Passing ajaxError per default
    ajaxError: function(error) {
      this.sendAction('ajaxError', error);
    }
  }
});

最后,我向应用程序路由添加了一些操作:

代码语言:javascript
复制
actions: {
  error: function(error) {
    this.send('ajaxError', error);
  },

  ajaxError: function(error) {
    this.ajaxError(error);
  },
}

为什么我有两个动作在做同样的事情?对路由的模型钩子上的错误调用error操作。我可以保留该操作,但在应用程序的其他部分,我显式地调用该操作,我想要一个更有意义的名称。因此,我还创建了一个ajaxError操作。你可以坚持一个动作,当然。

现在,您可以在任何地方使用它:

路由/控制器

this.ajaxError(error);

组件

this.sendAction('ajaxError', error);

当然,还需要将操作从要由应用程序路由处理的组件中传递出来:

{{some-component ajaxError="ajaxError"}}

这也适用于嵌套组件。您不需要在component.js文件中进一步显式地发送此操作,因为我们重新打开组件并将此操作传递到。

我希望我能在这方面帮助其他人。此外,欢迎任何反馈意见。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32078951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档