2015-09-01 60 views
1

我有一些我想要重构的代码(从控制器中提取服务器通信方法以分离服务)。
实施例:从异步方法抛出异常是否正常?

$http.post("/mypath", someData) 
    .success(function(request) { 
     if (request.ok) { 
      $scope.error = ""; 
      _refreshAppointments(); 
     } 
     else { 
      $scope.error = request.err; 
     } 
    }) 
    .error(function() { 
     $scope.error = "Error during communicating to server"; 
    }); 

我的当前的问题是错误处理(与旧$范围的通信)。所以我想抛出异常,而不是这样的行$scope.error = "Error during communicating to server"; 并将其捕获到控制器中。
这是个好主意吗?

+1

我们在服务中使用angular的$资源而不是$ http,然后我们的成功/错误回调在我们的控制器中完成。 – Catfish

回答

3

如果您在香草环境引发错误:

setTimeout(function() { 
    throw new Error(); 
}, 1); 

错误只是迷路。 (window.onerror会看到它虽然)

即使你:

try { 
    setTimeout(function() { 
     throw new Error(); 
    }, 1); 
} catch (e) { 
    console.log(e); 
} 

你不会看到错误。

你需要用的异步事件,如:

function mySetTimeout(callback, ms) { 
    setTimeout(wrap_in_try_catch(callback), ms); 
} 

mySetTimeout(function() { 
    throw new Error(); 
}); 

您现在可以在一个通用的错误处理程序捕获的错误,但你仍然不能赶上它周围的代码。

这是承诺进来的地方。并不是所有的库都以同样的方式承诺(或正确),所以我不知道你的库支持是多么的好。

大约您的代码如下:

$.ajax().then(function() { 
    throw new Error(); 
}).fail(e) { 
    console.log("it failed!", e); 
}); 

相反,如果您有:

$.ajax().then(function() { 
    throw new Error(); 
}); // throws something like: no fail callback for rejected value error 

那么你的全局错误处理程序将它捡起来。这确保没有错误可以通过裂缝滑落并迷路。

以这种方式获得Promise库以处理错误并非不可能,但设置起来有点棘手。一旦你有这个,但你很好。错误处理变得轻而易举。

你永远不会再写一个try-catch,只是一堆.fail()处理程序。

1

这绝对是个好主意提取REST/HTTP请求到模型/服务层和控制器使用这些服务。然后处理失败的操作意味着拒绝相应的承诺,在这种情况下,在承诺中抛出异常实际上意味着相同。

例如,这是您的服务/工厂如何能看起来像:

app.factory('dataService', function($http) { 
    return { 
     load: function() { 
      return $http.post("/mypath", someData).then(function(response) { 
       if (!response.data.ok) { 
        return throw new Error(response.request.err); 
        // or return $q.reject(response.request.err); 
       } 
       return response.request; 
      }); 
     } 
    }; 
}); 

和消费控制器将处理的诺言状态,解决(成功)或拒绝(失败/除外):

dataService.load().then(function(request) { 
    $scope.error = ""; 
    _refreshAppointments(); 
}) 
.catch(function(err) { 
    $scope.error = err || "Error during communicating to server"; 
});