【问题标题】:Angular 4, custom ErrorHandler doesn't recognize custom ErrorAngular 4,自定义 ErrorHandler 无法识别自定义错误
【发布时间】:2017-10-21 20:11:01
【问题描述】:

我尝试创建一个自定义全局ErrorHandler 并按照详细说明here 进行操作

application-error-handler(只是重要的部分)

@Injectable()
export class ApplicationErrorHandler extends ErrorHandler {

    constructor(private injector: Injector) {
        super(false);
    }

    handleError(error: any): void {

        if (error instanceof ApplicationError || error.originalError instanceof ApplicationError) {
            this.addError(error.originalError);
        }
        else {
            super.handleError(error);
        }
    }

应用模块

 providers: [
    {
        provide: ErrorHandler,
        useClass: ApplicationErrorHandler
    }
],

app.component(仅重要部分)

public ngOnInit(): void { 
    const error = new ApplicationError();
    error.message = "fehler";
    throw error;
} 

应用程序错误

export class ApplicationError implements Error {
    name: string;
    message: string;
    httpStatus?: number = 404;
    applicationStatus?: number;
    errorMessageTranslationkey: string;
    handled: boolean = false;
}

在我的 app.component 中,我抛出了一个 ApplicationError(在 ngOnInit 中),我的 ErrorHandler 被成功调用。 但是我在handleError 中的错误始终是Error 类型,而error.originalError 始终是undefined,无论我是否抛出自定义错误并且if 永远不会解析为true。

我不知道为什么以及如何发生这种情况。 我看到的是错误得到了,所以我假设,因为当我调试时我看到error: Error: [object: Object] at viewWrappedDebugError (vendor.bundle.js)

知道可能导致此问题的原因以及如何解决吗?

编辑 怀疑它与调试模式有关。只要我使用enableProdMode(); 启用 prodmode,它就会按预期工作。

这还没有真正回答我的问题。

如何在 Angular 的调试模式下处理我的自定义错误?

【问题讨论】:

  • 你能在你抛出错误的地方添加代码块吗?throw new ApplicationError()?另请注意,@NgModule() providers 属性必须是 this 定义中的数组。
  • 我在抛出错误的地方添加了代码。 provider 是一个错字。我更新了代码

标签: angular typescript error-handling


【解决方案1】:

您遇到此问题是因为ApplicationError 不是Error

您可以使用以下代码来创建自定义错误:

export class ApplicationError extends Error {

  httpStatus?: number = 404;
  applicationStatus?: number;
  errorMessageTranslationkey: string;
  handled: boolean = false;

  constructor(message?: string) {
    super(message);
    this.name = ApplicationError.name;
    Object.setPrototypeOf(this, ApplicationError.prototype);
  }
}

与创建自定义错误的主题相关,还请查看这些链接以全面了解该主题:

为什么这需要是 Error 的一个实例? 因为你的错误是通过以下方法传递的:

function viewWrappedDebugError(err, context) {
    if (!(err instanceof Error)) {
        // errors that are not Error instances don't have a stack,
        // so it is ok to wrap them into a new Error object...
        err = new Error(err.toString());
    }
    _addDebugContext(err, context);
    return err;
}

代码可在errors.ts 获得。

因此,如果您没有抛出 Error 实例,则会创建一个新实例。

在 ErrorHandler 中拦截未捕获的 Promise

另一种错误情况是,当您从 Angular 生命周期调用的方法(例如:处理程序、生命周期挂钩)中返回一个被拒绝的 Promise 时。

export class AppComponent implements OnInit {

  ngOnInit() {
    return new Promise((resolve, reject) => reject(new ApplicationError()));
  }
}

因此错误处理代码可能如下所示:

import {ErrorHandler, Injectable, Injector} from "@angular/core";
import {ApplicationError} from "./ApplicationError";

@Injectable()
export class ApplicationErrorHandler extends ErrorHandler {

  private errors: ApplicationError[] = [];

  constructor(private injector: Injector) {
    super(false);
  }

  handleError(error: any): void {

    if (error instanceof ApplicationError) {
      this.addError(error);
    }
    else {
      if(error.rejection instanceof ApplicationError) {
        this.addError(error.rejection);
      }
      else {
        super.handleError(error);
      }
    }
  }

  addError(error: ApplicationError) {
    this.errors.push(error);
  }
}

【讨论】:

  • 感谢您的详细回答。我能够修复它
  • 我需要做同样的事情,除了我需要发送邮件,你能提供我 plunker 吗?
  • 它被调用两次/多次,它应该只加载一次。
猜你喜欢
  • 1970-01-01
  • 2018-09-03
  • 2020-12-26
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 2016-01-30
  • 2012-08-04
  • 1970-01-01
相关资源
最近更新 更多