Angular ErrorHandler中的角度导航仅适用于zone.run()
我在angular(版本5.2.0)中为所有未处理的异常实现了一个全局错误处理程序 全局错误处理程序如下所示:Angular ErrorHandler中的角度导航仅适用于zone.run(),angular,angular-router,angular-errorhandler,Angular,Angular Router,Angular Errorhandler,我在angular(版本5.2.0)中为所有未处理的异常实现了一个全局错误处理程序 全局错误处理程序如下所示: import { Router } from '@angular/router'; import { ErrorHandler, Injectable, Injector, NgZone } from '@angular/core'; import { LoggingService } from '../services/logging.service'; @Injectable()
import { Router } from '@angular/router';
import { ErrorHandler, Injectable, Injector, NgZone } from '@angular/core';
import { LoggingService } from '../services/logging.service';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
private router: Router;
constructor(injector: Injector, private zone: NgZone, private loggingService: LoggingService) {
setTimeout(() => {
this.router = injector.get(Router);
});
}
handleError(error) {
this.loggingService.logErrorToApi(error);
this.zone.run(() => this.router.navigate(['/error']));
}
}
只有当我有呼叫this.zone.run(…)
时,路由才能工作。
如果删除此调用,则路由仅将路由错误
添加到URL,而不显示组件。ngOnInit也不叫它
如果我不得不使用这样的“黑客”来让我的路由工作,那么我的应用程序中似乎有一个配置错误
有人知道我需要做什么改变才能在没有区域呼叫的情况下运行吗
我的路线:
const appRoutes: Routes = [
{
path: 'error',
component: ErrorComponent
},
{
path: '',
component: HomeComponent,
canActivate: [CookieGuard]
},
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
HomeComponent,
PageNotFoundComponent,
ErrorComponent
],
imports: [
RouterModule.forRoot(appRoutes, { enableTracing: !environment.production }),
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
HttpClientXsrfModule,
],
providers: [
{ provide: ErrorHandler, useClass: GlobalErrorHandler },
ApiHttpClientService,
AppSettingsService,
CookieGuard,
LoggingService
],
bootstrap: [AppComponent]
})
export class AppModule { }
以下是我调用的错误组件:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'error',
templateUrl: './error.component.html',
styleUrls: ['./error.component.scss']
})
export class ErrorComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
我所做的就是调用
window.open(url)代码>
我认为你的路由器不工作,因为当一个Angular应用程序崩溃时,似乎什么都不工作了。至少这是我的经验。为了避免产生循环依赖,您的日志服务也应该位于app.module.ts中的providers数组中
我有这样的想法:
providers: [
CrashReportService,
{ provide: ErrorHandler, useClass: MyErrorHandler},
],
我从应用程序中删除了所有服务和模块,并将它们逐个添加回来,直到路由再次中断后,我自己发现了这个问题。模块浏览动画模块导致问题
GitHub=>上还有一个未解决的问题,错误处理程序中的错误超出了角度区域
例如:
@Injectable()
导出类GlobalErrorHandler实现ErrorHandler{
handleError(错误){
assertenangularzone();//这将抛出一个错误
}
}
因此,必须将导航打包到一个ngZone.run()
中是正常的。如果不这样做,angular将无法检测到更改,并且最终会出现错误导航和/或不负责任的页面。如果angular崩溃,将出现错误堆栈。Angular用于创建单页应用程序,不建议打开另一个选项卡…它不会使用“\u self”选项打开另一个选项卡。你做你想做的事。但我发现,向用户呈现一个新的未刷新页面并发送一条消息,要比让用户挂在崩溃页面上要好。如果您有更好的解决方案,或者知道在这种情况下推荐什么,我将非常高兴听到:)@VincentGagnon您的错误处理程序中是否存在相同的问题?我没有任何循环依赖性问题,但关于您最初提出的关于组件的问题,如果您不将其放在区域中,则该组件在错误后不会显示。run(),我只是使用了我在这里给出的解决方案。window.open(url,''u self');这也可能让人感觉像是黑客攻击,所以我不确定这是不是该走的路…@VincentGagnon我只有在尝试将路由器注入errorhandler时才会遇到“循环依赖性问题”。你能在没有循环依赖性问题的情况下注入它吗?你有没有尝试过类似于这个.injector.get(Router.navigate…
?您首先需要将注入的引用保存到Injector@Jota.Toledo如果我像这样尝试,我会得到同样的行为。错误路由已添加到url,但视图未更改:(除了未呈现的组件外,您是否在控制台中看到任何错误/日志?@Jota.Toledo除了导致调用错误处理程序的错误外,控制台中没有错误。我甚至从路由中看到了跟踪(因为启用了跟踪)。在html中,该组件被部分注入,但没有调用ngOnInit。该组件是否具有任何依赖项?能否尝试通过注入程序实例动态解析ErrorHandler的所有依赖项?能否提供一个简单的示例以供使用?我的LoggingService也在提供程序列表中。(我更新了我的问题)那么你就不必使用injector.get(…把它放在你的构造函数中,就像这样:constructor(private loggingService:loggingService,){}它可以正常地注入loggingService,但遗憾的是它并不能解决我的问题。