angular - 如何从 HttpErrorResponse 获取请求的正文/内容?[角度错误处理程序]
问题描述
假设我向post
服务器发送了一个创建用户的请求。如果服务器响应错误,我想从ErrorHandler
. 这样做的原因是,例如,当“创建用户”失败时,我想显示一个通知,其中包含从表单中获取的一些详细信息和一个按钮,用于将您重定向回相应的页面,并再次填充检索到的字段形式。
这就是我的ErrorHandler
样子:
@Injectable()
export class ErrorsHandler implements ErrorHandler {
constructor(
private injector: Injector,
) { }
handleError(error: Error | HttpErrorResponse) {
const errorsService = this.injector.get(ErrorsService);
const router = this.injector.get(Router);
const zone = this.injector.get(NgZone);
if (error instanceof HttpErrorResponse) {
// Server error happened
if (!navigator.onLine) {
return console.log('No Internet Connection.');
}
else if (error.status === HttpStatus.UNAUTHORIZED) {
console.log('ErrorsHandler handled HttpStatus Unauthorized. Navigating back to \'/login\' page.');
zone.run(() => router.navigate(['/login']));
}
else {
// Http Error
//How do I get the form from here? I need it for user notification.
return console.log('%c SERVER ERROR ', 'background: #222; color: #ff6961 ; font-size: 15px; border: 2px solid #ff6961;', error);
}
} else {
// Client Error Happend
// Send the error to the server and then
// redirect the user to the page with all the info
errorsService
.log(error)
.subscribe(errorWithContextInfo => {
router.navigate(['/error'], { queryParams: errorWithContextInfo });
});
}
}
}
解决方案
我用拦截器对@GabrielLopez 的回答有所不同:
import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse}
from "@angular/common/http";
import {Observable, throwError} from "rxjs";
import {catchError, tap} from "rxjs/operators";
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>,
next: HttpHandler):
Observable<HttpEvent<any>> {
return next.handle(req)
.pipe(
tap((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
console.log(`processing response ${ev.status}`);
}
}),
catchError(response => {
console.log('Processing http error', response);
if (response.error) {
return throwError(response.error);
} else if (response.message) {
return throwError(response.message);
} else {
return throwError(response);
}
})
);
}
}
和加布里埃尔的回答一样,拦截器需要在 app.module.ts 中声明providers
:
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true
},
...
我对此不满意,因为这可能意味着 Angular HttpClient 错误处理过度设计。从 REST API 调用中获取错误应该不难。
推荐阅读
- apache-flink - Apache Flink:DataStream API 中的侧输出和 split() 有什么区别?
- google-analytics - 如何在 React Ga 中添加自定义维度?
- python - 无法允许可能不是警报的通知
- java - Sun MonitoredHost 类的 Java 10 替代品
- javascript - _.sumBy 数组中相同键的总计
- python - MailGun API 批量发送 Python
- ruby-on-rails - MAC 中的 Pod 更新
- javascript - Jquery 复选框选中和未选中事件
- sql - 在sql表函数中将某些字符包装在标签周围
- python - 抑制 Jupyter Notebook 魔术命令通知