Angular 4 + zonejs:路由在未捕获的错误后停止工作
Angular 4 + zonejs: routing stops working after uncaught error
如果在路由过程中组件(构造函数或 ngOnInit)出现未捕获的错误,导航将不再工作。
即使存在全局 ErrorHandler 和 RouterModule 的 ErrorHandler,也会发生这种情况,同时添加 ZoneListener 以确保 - 参见 app.module.ts
此处的最小示例:
https://embed.plnkr.co/L19S3hKWyqgKUIT1EJlI/preview
确保打开控制台。单击 "Example Component" 后,由于 ExampleFormComponent 中的强制错误,会出现一些堆栈跟踪。之后您将无法导航回 "Home".
如何处理意外的、未捕获的错误以确保它们不会破坏整个应用程序?
我会做一些解决方法,例如:
let hasRouterError = false;
@Injectable()
export class MyErrorHandler implements ErrorHandler {
constructor(private inj: Injector) {}
handleError(error: any): void {
console.log('MyErrorHandler: ' + error);
if(hasRouterError) {
let router = this.inj.get(Router);
router.navigated = false;
}
//throw error; // it is necessarily otherwise handleError won't be executed during next error
}
}
export function MyRouterErrorHandler(error: any) {
console.log('RouterErrorHandler: ' + error);
hasRouterError = true;
throw error;
}
我们必须使用自定义 RouteReuseStrategy
:
export class PreventErrorRouteReuseStrategy implements RouteReuseStrategy {
shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; }
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
if(hasRouterError) {
hasRouterError = false;
return false;
}
return future.routeConfig === curr.routeConfig;
}
}
它与DefaultRouteReuseStrategy
唯一不同的是这个代码
if(hasRouterError) {
hasRouterError = false;
return false;
}
不要忘记将它添加到提供程序数组中:
import { RouteReuseStrategy } from '@angular/router';
...
{ provide: RouteReuseStrategy, useClass: PreventErrorRouteReuseStrategy },
你可以在Modified Plunker
试试
如果在路由过程中组件(构造函数或 ngOnInit)出现未捕获的错误,导航将不再工作。
即使存在全局 ErrorHandler 和 RouterModule 的 ErrorHandler,也会发生这种情况,同时添加 ZoneListener 以确保 - 参见 app.module.ts
此处的最小示例: https://embed.plnkr.co/L19S3hKWyqgKUIT1EJlI/preview
确保打开控制台。单击 "Example Component" 后,由于 ExampleFormComponent 中的强制错误,会出现一些堆栈跟踪。之后您将无法导航回 "Home".
如何处理意外的、未捕获的错误以确保它们不会破坏整个应用程序?
我会做一些解决方法,例如:
let hasRouterError = false;
@Injectable()
export class MyErrorHandler implements ErrorHandler {
constructor(private inj: Injector) {}
handleError(error: any): void {
console.log('MyErrorHandler: ' + error);
if(hasRouterError) {
let router = this.inj.get(Router);
router.navigated = false;
}
//throw error; // it is necessarily otherwise handleError won't be executed during next error
}
}
export function MyRouterErrorHandler(error: any) {
console.log('RouterErrorHandler: ' + error);
hasRouterError = true;
throw error;
}
我们必须使用自定义 RouteReuseStrategy
:
export class PreventErrorRouteReuseStrategy implements RouteReuseStrategy {
shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; }
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
if(hasRouterError) {
hasRouterError = false;
return false;
}
return future.routeConfig === curr.routeConfig;
}
}
它与DefaultRouteReuseStrategy
唯一不同的是这个代码
if(hasRouterError) {
hasRouterError = false;
return false;
}
不要忘记将它添加到提供程序数组中:
import { RouteReuseStrategy } from '@angular/router';
...
{ provide: RouteReuseStrategy, useClass: PreventErrorRouteReuseStrategy },
你可以在Modified Plunker
试试