【问题标题】:unable to catch 404 error (resource not found) in Ember JS setupController hook while assigning model to the template在将模型分配给模板时,无法在 Ember JS setupController 挂钩中捕获 404 错误(找不到资源)
【发布时间】:2014-05-12 09:11:24
【问题描述】:

我在 emberjs 应用程序中有一个路由 /users/:user_id,我正在为 App.UserRoute 类的 setupController 挂钩中的模板分配一个模型:

controller.store.find('user', model.id).then(onSuccess, onError);

var onSuccess = function(user) {

if(user) {
    // reload Model to forcefully fetch from server
    user.reload().then(function() { /* some processing */ }, function(error_response) { /* some error handling */ });

    // assign model for user
        controller.set('model', user);
    }
};

var onError = function(reason) { /* some error handling */ };

现在,当我正在寻找不存在的用户 ID 时,这给了我来自服务器的错误 404。我正在尝试捕获此错误并显示适当的消息并重定向到所有用户的列表 (/users)。但我无法捕捉到它,并且我从 ember 收到一个错误:Error while loading route: undefined。我怎样才能做到这一点?

【问题讨论】:

    标签: rest ember.js error-handling http-status-code-404 ember-data


    【解决方案1】:

    真正的事情是您将undefined 传递给您的then 方法。您应该将回调函数的声明移到承诺代码之前。

    var onSuccess = function(user) {
    
      if(user) {
        // reload Model to forcefully fetch from server
        user.reload().then(function() { /* some processing */ }, function(error_response) { /* some error handling */ });
    
        // assign model for user
            controller.set('model', user);
        }
      };
    
    var onError = function(reason) { /* some error handling */ };
    
    controller.store.find('user', model.id).then(onSuccess, onError);
    

    【讨论】:

      【解决方案2】:

      原因是您自己正在捕获故障并通过then 的第二个参数对其进行处理。这将失败变为成功。您将需要重新抛出错误,以便它被您定义的 error 钩子拾取。一种方法是

      user.reload().then(
          function() { /* some processing */ }, 
          function(error_response) { /* some error handling */ }.catch(RSVP.rethrow)
      });
      

      它也很可能会起作用

      user.reload().then(function() { /* some processing */ }, 
          function(error_response) { 
              /* some error handling */
              throw "reload failed";
          }
      );
      

      更一般地,考虑以下代码:

      rejected_promise.then(
          success1 /* won't be called */
          function rejected() { return 0; }
      )
      .then(
          success2 /* will be called */
          rejected2 /* won't be called */
      );
      

      这里,rejected2 不会被调用;相反,success2 将是。这是因为拒绝处理程序被认为是履行承诺(使其成功),除非它重新抛出。

      【讨论】:

        【解决方案3】:

        我认为有一些实现细节可以改进:

        1) 您不需要在控制器中设置模型。 Ember 将其分配给路由 model hook 中的 promise 解析的值。

        model: function(params) {
        
          var user = this.store.getById('user', params.id);
        
          if (user) {
            return user.reload();
          } else {
            return this.store.find('user', params.id);
          }
        
        }
        

        2) 您可以在路由的错误事件处理程序中捕获您的承诺错误。

            actions: {
              error: function(error) {
                 // print error
                this.transitionTo('users');
              }
            }
        

        您可以查看Ember Guide 以检查路由器如何管理错误和加载子状态。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-17
          • 1970-01-01
          • 2017-01-28
          相关资源
          最近更新 更多