我正在尝试处理我的angular应用程序中的错误,但是全局错误处理程序不起作用。
我正在使用ngrx进行状态管理,并且在我的angular应用程序中有一个全局错误处理程序。我正在使用catchError运算符按照建议的here处理ngrx / effects中的错误。但是现在我无法使用全局错误处理程序,并且必须在每个效果中都使用catchError。
// ErrorHandler
handleError(error: Error | HttpErrorResponse) {
const router = this.injector.get(Router);
console.error("Error intercepted.", error);
this.spinner.hide();
if (error instanceof HttpErrorResponse) {
if (!navigator.onLine) {
this.showError('No internet connection');
} else {
if (error.error.message) {
this.showError(`${error.error.message}`);
} else {
this.showError(`${error.status} - ${error.message}`);
}
}
} else {
this.showError("Unknow error.");
router.navigate(['/dashboard']);
}
}
// ngrx效果
export class EffectError implements Action {
readonly type = '[Error] Effect Error';
}
@Effect()
UserAuth: Observable < Action > = this.actions.pipe(
ofType(SigninActions.AUTHENTICATE_USER),
switchMap((action: SigninActions.AuthenticateUser) =>
this.signinService.signin(action.payload.emailAddress, action.payload.password).pipe(
map((loginContext: LoginContext) => {
console.log("LOGIN_CONTEXT", loginContext);
return new SigninActions.AuthenticateUserSuccess(loginContext)
}),
//CatchError
catchError(() => of(new EffectError()))
)
)
);
我正在使用catchError运算符,以便每当发生错误并且全局错误处理程序显示不同的错误消息时,效果都不会中断。
答案 0 :(得分:1)
问题是catchError
中的@Effect
将吞噬错误,并且不会传播回ErrorHandler
。
您可以找到很多有关如何执行此操作的文章,但总而言之,您应该执行HttpInterceptor
并使用catchError
处理HttpHandler
发回的错误:
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError(error => {
if (error instanceof HttpErrorResponse) {
// check for internet connection
if (!navigator.onLine) {
this.showError('No internet connection');
}
// handle HTTP errors
switch (error.status) {
case 401:
// do something
break;
case 403:
// do something else
break;
default:
// default behavior
}
}
// need to rethrow so angular can catch the error
return throwError(error);
}));
}
}
然后,当然,不要忘记在AppModule中使用HTTP_INTERCEPTORS
注入令牌来提供错误拦截器的实现:
import { HTTP_INTERCEPTORS } from '@angular/common/http';
...
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
],
通过这种方式,您可以同时处理两个错误...
ErrorHandler
用于客户端错误(javascript,角度等等)HttpInterceptor
用于HTTP请求关于如何处理角度错误的好方法,这是一篇不错的文章:
https://blog.angularindepth.com/expecting-the-unexpected-best-practices-for-error-handling-in-angular-21c3662ef9e4
答案 1 :(得分:0)
假设您的globalerrorhandler如下:
@Injectable()
export class GlobalErrorHandler extends ErrorHandler {
public handleError(error: Error | HttpErrorResponse) { }
}
您可以从catcherror中抛出错误(在您的效果中),并且现在将调用handleError方法。
example.effect.ts
catchError((err) => {
const error: string = err.message;
this.store.dispatch(exampleActions.ResultFailure({ error }));
throw err;
})