AngularJS$http承诺异常不会冒泡
AngularJS $http promise exception not bubbling up
我遇到了一个问题,即$http
承诺没有从执行它的服务冒泡到调用服务方法的任何地方。
我在服务中有一个返回$http
承诺的.authozire()
方法,如下所示:
// auth.service.js
function authorize(authParams) {
var request = {
method: 'POST',
url: _apiUrl + 'oauth/token',
data: authParams
};
return $http(request)
.then(
function successHandler(response) {
// Correctly executed when success
$log.debug('authService :: authorize => success', response);
},
function errorHandler(response) {
// Correctly executed when error
$log.debug('authService :: authorize => error', response);
}
);
}
上面的 success
和 error
方法(请不要说我已经没有使用 .success()
和 .error()
方法,因为它们已被弃用)在每种情况下都可以正常工作,但是当我从控制器调用此方法时,它无法按预期工作,如下所示:
// signin.controller.js
function submit() {
authService.authorize(vm.formData)
.then(
function successHandler(response) {
// Always executed even when there's an error
$log.debug('SignInController :: submit :: authService.authorize() => success', response);
},
function errorHandler(response) {
// NEVER executed
$log.debug('SignInController :: submit :: authService.authorize() => error', response);
}
);
}
始终调用successHandler
的第一个方法,即使出现错误并且服务执行了自己的errorHandler
。
似乎服务返回的承诺只是一个简单的承诺,它接受.then()
,但不区分success
和fail
,如文档中解释的那样:
返回一个承诺,当请求成功或失败时,该承诺将解析为响应对象。
所以。。。我错过了什么吗?以前有人遇到过这样的问题吗?
谢谢!
我相信你和我了解承诺时有类似的感觉。 这是我提出的一个与你相似的问题的答案。我只是惊讶于错误没有传播。使用克里斯·科瓦尔的Q。如果链式承诺的整个生命周期中抛出任何错误,我应该如何捕捉?
引用这个答案:
处理的拒绝就像捕获的异常。它停止传播 既然很好,它就被处理了。如果您想处理拒绝和 保持拒绝,你需要重新抛出,再次,就像在同步中一样 法典。
try {
throw new Error();
} catch(e){
// handle error
}
// no error here this code will keep running.
如果你想让它继续拒绝并处理它,你需要重新抛出:
try {
throw new Error();
} catch(e){
// handle error
throw e;
}
// this code will not run
承诺也是如此,就像你写的那样。这不是特别 关于承诺很奇怪,同步异常也是这样工作的。 如果你想传播 - 你重新抛出,否则 - 错误是 认为已处理。
- 因此,您可以继续在服务中记录错误,并通过在服务中添加
return $q.reject(response);
来引发链中下一部分收到的相同错误。您也可以在服务结束时说throw response;
而不返回,它会将错误带到链的下一部分。 - 您可以决定不在服务中记录错误,而是直接在控制器中处理它。
个人会选择1,但那是因为当承诺没有记录他们的错误时,我无法忍受,在没有日志记录的情况下很难追踪什么。
在 auth.service.js
错误处理程序必须返回被拒绝的承诺:
return $q.reject(response);
问题是您已经在身份验证服务中处理承诺的回调。
要解决此问题,我们有两种可能的解决方案:
在授权方法中创建一个承诺并返回它。
function authorize(params) {
// create a promise object
var dfd = $q.defer();
var request = []; // request params here
$http(request).then(
function SuccessHandler(res) {
def.resolve(res);
},
function ErrorHandler(res) {
dfd.reject(res);
});
return dfd.promise();
}
另一种方法是发送 http 对象而不处理方法授权中的回调
return $http(request);
- Meteor如何接收HTTP请求
- 在我的情况下,如何进行http请求
- //而不是在src=“”上使用http://"属性
- 我无法使用angularJs($http)访问服务器
- AJAX简单错误.XMLHttpRequest无法加载http://localhost/mpl/getPage.php.
- 如何将PHP get查询转换为Meteor's HTTP.get()
- 角度异步http自动完成
- 什么's本地node.js服务器和python简单http服务器之间的区别
- 角度http服务器页面刷新404s
- http.listen()在运行时接受终端命令
- 在javaservlet doPost方法中启动线程时,无法返回异常消息
- IIS动态HTTP响应标头
- web配置http到https重定向异常
- Eclipse HTTP服务器空指针异常
- Angular-使用httpBackend测试http服务会引发意外异常
- AngularJS$http承诺异常不会冒泡
- 如何将异常从 PHP 抛出到 Angular $http 服务
- Vert-x 3.3.2 HTTP客户端异常处理程序
- HTTP响应中数组的异常表示(array: 0x7f7298c057f0)
- http请求后GWT中未捕获的异常