在自定义错误处理程序

时间:2017-02-28 07:56:51

标签: angular angular2-routing

你好我在Angular的自定义异常处理程序中添加了一个路由导航,但我遇到的问题是,当一个Angular组件的onInit触发错误时,它会进入一个错误循环:

错误:无法激活已激活的插座

这是我的组件的代码:

    import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

@Injectable()
export class ErrorService implements ErrorHandler  {

  constructor(
    private injector: Injector
  ) { }

  get router(): Router {
    return this.injector.get(Router);
  };


  handleError(error: any): void {
    console.error(error);
    this.router.navigate(['error', { error: error }], { skipLocationChange: true});
  }

}

这些我的路线:

export const routes: Routes = [
  { path: '', redirectTo: 'browser', pathMatch: 'full' },
  { path: 'browser', loadChildren: './modules/browserui#BrowserUiModule' },
  { path: 'error', component: ErrorComponent, data: { title: 'Generic error' } },
  { path: '**', component: ErrorComponent, data: { title: '404 not found' } }
];

有什么想法吗?谢谢!

3 个答案:

答案 0 :(得分:4)

@jonas和其他人,我实际上在全局错误处理程序中找到了更好的方法。我们甚至不需要setTimeout,在我的情况下,这还不够,因为它是部分路由(它是路由,但前一页的一部分保留在屏幕上,有点奇怪)。

无论如何,我在Angular回购中找到了一个GitHub post,它说要使用zone。所以在我的情况下,我想抓住401并重定向到登录页面,代码就像这样简单:

handleError(error: any) {
   console.error(error);
   if (error.status === 401) {
     zone.run(() => router.navigate(['/login']));
   }
}

现在它按预期工作,没有任何副作用。

答案 1 :(得分:2)

I finally got this to work. My solution was to encapsulate the navigate call inside a setTimeout() function, so my solution for you would look like this:

handleError(error: any): void {
    console.error(error);
    setTimeout(() => this.router.navigate(['error', { error: error }], { skipLocationChange: true}));
  }

  • Angular: 4.4.4
  • Angular-cli: 1.4.6
  • Typescript: 2.5.3

答案 2 :(得分:0)

我以这种方式解决它:

@Injectable()
export class ErrorService {

  constructor(private router: Router, private zone: NgZone) {
  }

  navigate(url: string) {
    this.zone.run(() => this.router.navigate([url]));
  }

}
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {

  private errorService: ErrorService;

  constructor(private injector: Injector) {
  }

  handleError(error: Error): void {
    //retarda a chamada para evitar erro de ciclo
    this.errorService = this.injector.get(ErrorService);

    console.log("Tratador genérico de erro.")
    console.log(error);
    let msg = '';
    //erro de servidor
    if (error instanceof HttpErrorResponse) {
      if (error.status == 401) {
        msg = 'Por favor, faça a login novamente.';
        this.errorService.navigate('/login');
        alert(msg);
      }
    }   
  }
}