我正在为我的Angular应用程序构建一个自定义错误处理程序来处理错误,然后将错误添加到列表中以显示给用户。错误处理程序按预期工作;它捕获错误,使用Angular Injector
,获取将错误添加到列表所需的服务实例,并将其添加到列表中。然后,该服务应使用Rxjs Subject.next()
函数将该列表发送给已订阅该列表的所有人。这就是奇怪发生的地方。
有关背景信息,我设置了一个按钮,可以对无效的URL进行HTTP调用,这样就可以根据需要创建错误,并且可以被应用程序捕获。
第一次单击该按钮时,会出现错误,它会被捕获并发送到服务,但它不会显示在页面上(循环显示该列表以在组件中输出它们)。第二次单击该按钮时,屏幕上会显示错误。与第三个和第四个相同,但屏幕上的警报总是少于阵列中的警报。
然后,当您第一次从阵列中删除警报时,它肯定会被删除,但您无法分辨,因为最终会显示额外警报。后续点击会删除其他警报。
现在让我们回到向阵列添加警报。第一次单击按钮时,屏幕上没有任何反应,但如果您console.log
数组,则可以看到它已向项目添加了项目。再次单击它,屏幕上会显示警告。
因此,如果有意义的话,似乎每次点击实际上都会排放或传递数组一次。我不确定为什么会这样。这应该是非常直接的。任何帮助将不胜感激。
您可以看到工作示例on StackBlitz here。
答案 0 :(得分:0)
经过多次尝试,我已经知道为什么你的实际代码不能正常工作。是因为你的ErrorHandler
捕获了Angular中的所有异常。而且你要保持提醒,而不是让角度传播这个必须管理的例外。
Example of what i try to explain
所以我已将ErrorHandler
替换为HttpInterceptor
:
import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor,HttpHandler, HttpRequest, HttpEvent,HttpErrorResponse } from '@angular/common/http';
import { Observable,empty, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AlertToasterService } from '../alert-toaster/alert-toaster.service';
@Injectable()
export class ErrorHandlerService implements HttpInterceptor {
constructor(private alertToasterService: AlertToasterService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(catchError((err: HttpErrorResponse) => {
let errorMessage= 'An unknown error occurred.';
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
errorMessage = err.error.message;
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
errorMessage = err.message;
}
this.alertToasterService.addAlertToList({
level: 'danger',
message: errorMessage,
dismissible: true
});
return throwError(err);
}));
}
}
在我的app.module上添加引用:
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorHandlerService,
multi: true
},
与您的问题无关,但您也可以查看我如何更改app-alert-toaster
来管理onPush策略,并且只管理html端内的Observable异步管道。