Angular HttpClient retryWhen块错误处理:传递HttpResponse至错误处理器
解决Angular 5中PUT请求重试后传递原始HttpErrorResponse的问题
你遇到的问题很典型——原来的retryWhen逻辑在重试耗尽后抛出了自定义字符串错误,导致handleHttpError无法拿到包含响应详情的HttpErrorResponse对象。我们只需要调整重试逻辑,保留最后一次失败的原始错误即可解决。
问题根源
你的代码里用concat(Observable.throw("error occurred"))抛出了自定义错误,这直接替换了原本的HttpErrorResponse实例,而错误处理器期望接收的是包含请求状态码、响应体等关键信息的HttpErrorResponse对象,自然无法满足需求。
修正后的实现
我们可以用scan操作符跟踪重试次数,当达到重试上限时,直接抛出最后一次的原始错误,而不是自定义错误。这样错误处理器就能拿到完整的错误上下文:
import 'rxjs/add/operator/retryWhen'; import 'rxjs/add/operator/scan'; import 'rxjs/add/operator/delay'; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; // ... return this.http.put<string>(URL, value) .retryWhen(err => { // 用scan累计重试次数,初始值设为0 return err .scan((retryCount, error) => { // 当重试次数达到3次(原始请求+3次重试=共4次请求),抛出原始错误 if (retryCount >= 3) { throw error; } return retryCount + 1; }, 0) .delay(3000); // 每次重试间隔3秒 }) .catch(err => this.handleHttpError(err));
代码说明
scan操作符:用来跟踪重试次数,每次错误触发时计数加1。当计数达到3时,说明已经完成了3次重试,此时直接抛出当前的原始HttpErrorResponse。- 保留原始错误:不再用自定义字符串替换错误,确保
handleHttpError能拿到包含status、error、response等属性的完整错误对象。 - 匹配需求的重试逻辑:初始请求失败后,会自动重试3次,每次间隔3秒,完全符合你的预期。
错误处理器示例
现在你的handleHttpError可以正常处理HttpErrorResponse了:
private handleHttpError(error: HttpErrorResponse) { // 访问错误详情 console.error('请求失败状态码:', error.status); console.error('响应体内容:', error.error); // 根据业务需求处理错误,比如返回友好提示的Observable return Observable.throw(`请求失败:${error.status} ${error.statusText}`); }
注意事项
Angular 5对应的RxJS 5.x版本需要单独导入操作符才能使用,所以要确保你已经导入了scan、delay等用到的操作符。
内容的提问来源于stack exchange,提问作者Dave S.
相关产品推荐
相关产品推荐

