【问题标题】:Application becomes unresponsive after encountering an exception遇到异常后应用程序变得无响应
【发布时间】:2019-05-03 23:54:06
【问题描述】:

如何告诉 Angular 2 在遇到异常时不要阻塞整个应用程序?

我不确定这是否可能,因为 Google 并没有就此向我提供启发。 但它似乎对任何单页 Web 应用程序都至关重要。

每当 Angular 2 遇到异常并抛出错误时,整个应用程序就会变得无响应。

我知道在 JavaScript 中

try {
  doSomething();
}
catch(err) {
  handleErrors(err);
}

或许能解决问题。

但我只是想知道是否有任何 Angular 特定的解决方案或解决方法?

【问题讨论】:

标签: angular


【解决方案1】:

在 Angular 2 最终版本上,您可以实现自定义 ErrorHandler (Angular 2 docs example):

import {NgModule, ErrorHandler} from '@angular/core';

class MyErrorHandler implements ErrorHandler {
  handleError(error) {
    // do something with the exception
  }
}

@NgModule({
  providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
})
class MyModule {}

【讨论】:

    【解决方案2】:

    更新:

    2.0.0 RC.6将名称从ExceptionHandler更改为ErrorHandlercall更改为handleError

    @Injectable()
    class MyErrorHandler implements ErrorHandler {
    
      handleError(error) {
        // do something with the exception
      }
    }
    
    
    @NgModule({
      directives: [MyApp],
      providers: [
        {provide: ErrorHandler, useClass: MyErrorHandler}
      ]
    })
    export class AppModule {}
    

    另见this

    原文:

    实现a custom exception handler:

    @Injectable()
    class MyExceptionHandler implements ExceptionHandler {
      call(error, stackTrace = null, reason = null) {
        // do something with the exception
      }
    }
    
    
    @NgModule({
      directives: [MyApp],
      providers: [
        {provide: ExceptionHandler, useClass: MyExceptionHandler}
      ]
    })
    export class AppModule {}
    

    另请参阅 thisthis

    如果这允许应用程序在异常后继续,我还没有尝试过,但我认为值得一试。 至少应该可以自动重新加载页面。

    一般情况下,当有恢复的方法时,应尽可能接近原因处理异常。

    【讨论】:

    • 我试了一下,成功重定向到不易出错的首页,总比没有好。但我还没有找到一种方法让应用程序即使在出现异常后也能保持响应,这通常不是一个好方法,但作为后备,它可能会很好。
    • 我想除了早点捕获异常之外别无他法。异常冒泡到 Angular 并且 Angular 无法知道如何处理您的自定义“错误”。它运行您的异常处理程序并退出。
    【解决方案3】:

    我尝试按照 @GünterZöchbauer

    的指示实施自定义异常处理程序

    这对我有用


    使用 CustomExceptionHandler 引导您的应用程序。

    import {ExceptionHandler} from 'angular2/core';
    
    class _ArrayLogger {
      res = [];
    
      log(s:any):void {
        this.res.push(s);
      }
      logError(s:any):void {
        this.res.push(s);
      }
      logGroup(s:any):void {
        this.res.push(s);
      }
      logGroupEnd() {
        if(this.res.length) {
    
          //this section executes if any error is logged by angular. 
    
          //do your stuff here
    
          /*e.g
    
            if(location.pathname !== 'dashboard') {
               window.location.href = '/dashboard'; // condition is required to prevent infinite loop
            }
    
            */
         }
      };
    }
    
    export class CustomExceptionHandler extends ExceptionHandler {
      constructor() {
        super(new _ArrayLogger(), true);
      }
    
      call(error, stackTrace = null, reason = null) {
        super.call(error, stackTrace, reason);
      }
    }
    
    bootstrap(MyApp, [provide(ExceptionHandler, {useClass: CustomExceptionHandler})])
    

    【讨论】:

    • 我假设您仍然需要重新加载所有组件。你试过了吗?
    • 是的,在logGroupEnd() { if(this.res.length) { 我要做window.location.href = '/' 或其他一些默认路径
    【解决方案4】:

    我认为当您使用 RxJS Observables 时可能会出现此问题,当它们遇到任何错误时会取消订阅。 如果您遇到这种情况,您可能需要:

    1. .subscribeonNext 处理程序中使用try...catch 而不是在onError 处理程序中捕获异常。
    2. .subscribeonError 处理程序中重新订阅。

    【讨论】:

    • 如何访问这个 onNext 处理程序。你能详细说明一下语法吗?
    • @jackOfAll 当然。当你有一个 Observable 对象时,你可以在它上面调用 subscribe 方法,即:observable.subscribe(myHandler)subscribe 方法实际上需要 3 个参数。第一个称为onNext,第二个 - onError 和第三个 - onCompleted。你可以在这里看到更多:github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/…。如果您还有其他问题,或者我的回答没有涵盖您的意思,请不要犹豫:)
    • 谢谢米哈尔。我尝试将整个 subscribe 方法包装在 try catch 块中。我还尝试将带有每个回调参数的代码(onNext 和 onError,我还没有探索过 onCompleted )放在 try catch 块中。但在每种情况下,我都无法捕捉到异常!在我的情况下,当我从我的 API 收到 404 响应并最终进入 onError 回调时,就会发生崩溃
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多