Angular 错误处理程序和 HttpErrorResponse
Angular ErrorHandler and HttpErrorResponse
今天我决定更多地研究我的 Angular 应用程序的一些集中式错误报告。我使用了 Michael Karén (https://medium.com/angular-in-depth/expecting-the-unexpected-best-practices-for-error-handling-in-angular-21c3662ef9e4) 在 Medium 上发表的一篇很棒的文章,解释了如何处理客户端和服务器端问题并记录它们。
在我的示例项目中,我有一个非常简单的拦截器:
export class HttpInterceptor implements NgHttpInterceptor {
constructor(
private auth : AuthService
) { }
intercept(request : HttpRequest<any>, next : HttpHandler) : Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
retry(1),
catchError((error : HttpErrorResponse) => {
return throwError(error);
})
);
}
}
而且非常简单的 ErrorHandler:
@Injectable()
export class AppErrorHandler implements ErrorHandler {
constructor(
private readonly injector : Injector
) { }
handleError(error : Error | HttpErrorResponse) {
/** injectables */
const errorService = this.injector.get(ErrorService);
const loggingService = this.injector.get(LoggingService);
/** initialize empty variables */
let message : string;
let stackTrace : string;
if (error instanceof HttpErrorResponse) {
console.log('server');
} else {
console.log('client');
}
}
}
是的,到目前为止它还不是真正的日志记录,但这不是问题。然而,我注意到,当使用 Angular 的 HttpClient
和 1) 使用 toPromise()
方法而不是订阅,或 2) 订阅错误响应时,错误处理程序说error instanceof HttpErrorResponse
是错误的。所以..
这将正确记录 'server':
this.httpClient.get('foo').subscribe()
这将错误地记录 'client':
this.httpClient.get('foo').subscribe(
data => console.log,
error => console.error
)
这也会错误地记录 'client':
await this.httpClient.get('foo').toPromise()
因为我完全不明白这里到底发生了什么,为什么这是个问题,有人能帮我纠正 HTTP 错误的错误报告吗?我正在考虑在 HttpInterceptor 中记录这些错误,但是在抛出它们时,ErrorHandler 会再次将它们记录为客户端错误。
为什么要使用回调
使用回调主要是因为所有这些调用都在各自的服务中。例如,用户服务从一个端点获取数据,对数据做一些事情,然后解决一个承诺(或者完成观察者,不管是什么)
编辑:
我创建了一个 StackBlitz 示例来说明问题:https://stackblitz.com/edit/angular-ivy-gjtxk2
我已经查看了您的 StackBlitz 示例。如果您在处理 HTTP-Broken 2
中的错误时遇到问题,请修改您的代码以捕获错误并将其抛给 GlobalHandler -
httpBroken2() {
this.httpClient.get(this.randomUrl()).pipe(catchError((errors: HttpErrorResponse) => {
// anything you want to do (i.e. modify error)
return throwError(errors);
})).subscribe(
(data) => {
alert(data);
}
)
}
今天我决定更多地研究我的 Angular 应用程序的一些集中式错误报告。我使用了 Michael Karén (https://medium.com/angular-in-depth/expecting-the-unexpected-best-practices-for-error-handling-in-angular-21c3662ef9e4) 在 Medium 上发表的一篇很棒的文章,解释了如何处理客户端和服务器端问题并记录它们。
在我的示例项目中,我有一个非常简单的拦截器:
export class HttpInterceptor implements NgHttpInterceptor {
constructor(
private auth : AuthService
) { }
intercept(request : HttpRequest<any>, next : HttpHandler) : Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
retry(1),
catchError((error : HttpErrorResponse) => {
return throwError(error);
})
);
}
}
而且非常简单的 ErrorHandler:
@Injectable()
export class AppErrorHandler implements ErrorHandler {
constructor(
private readonly injector : Injector
) { }
handleError(error : Error | HttpErrorResponse) {
/** injectables */
const errorService = this.injector.get(ErrorService);
const loggingService = this.injector.get(LoggingService);
/** initialize empty variables */
let message : string;
let stackTrace : string;
if (error instanceof HttpErrorResponse) {
console.log('server');
} else {
console.log('client');
}
}
}
是的,到目前为止它还不是真正的日志记录,但这不是问题。然而,我注意到,当使用 Angular 的 HttpClient
和 1) 使用 toPromise()
方法而不是订阅,或 2) 订阅错误响应时,错误处理程序说error instanceof HttpErrorResponse
是错误的。所以..
这将正确记录 'server':
this.httpClient.get('foo').subscribe()
这将错误地记录 'client':
this.httpClient.get('foo').subscribe(
data => console.log,
error => console.error
)
这也会错误地记录 'client':
await this.httpClient.get('foo').toPromise()
因为我完全不明白这里到底发生了什么,为什么这是个问题,有人能帮我纠正 HTTP 错误的错误报告吗?我正在考虑在 HttpInterceptor 中记录这些错误,但是在抛出它们时,ErrorHandler 会再次将它们记录为客户端错误。
为什么要使用回调 使用回调主要是因为所有这些调用都在各自的服务中。例如,用户服务从一个端点获取数据,对数据做一些事情,然后解决一个承诺(或者完成观察者,不管是什么)
编辑:
我创建了一个 StackBlitz 示例来说明问题:https://stackblitz.com/edit/angular-ivy-gjtxk2
我已经查看了您的 StackBlitz 示例。如果您在处理 HTTP-Broken 2
中的错误时遇到问题,请修改您的代码以捕获错误并将其抛给 GlobalHandler -
httpBroken2() {
this.httpClient.get(this.randomUrl()).pipe(catchError((errors: HttpErrorResponse) => {
// anything you want to do (i.e. modify error)
return throwError(errors);
})).subscribe(
(data) => {
alert(data);
}
)
}