Angular 4中HTTP错误的集中处理 [英] Centralized handling for HTTP errors in Angular 4

查看:234
本文介绍了Angular 4中HTTP错误的集中处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果HTTP请求失败,我想通知用户,而不必为每个HTTP请求编写其他代码.

我有一个适用于角度2的原型:

@Injectable()
export class MyErrorHandler extends ErrorHandler {

  constructor() {
    super(false);
  }

  handleError(error: any) {
    this.tellUser(error);
    super.handleError(error);
  }

  tellUser(error: any) {
    // dig for the root cause
    if (error.rejection) {
      error = error.rejection;
    }
    if (error instanceof ViewWrappedError) {
       error = error.originalError;
    }

    let message;
    if (error instanceof Response) {
      // TODO: localize and display nicely
      const messages = {
        0: "Could not connect to server",
      }
      message = messages[error.status] || ("The server reported a system error (HTTP " + error.status + ")");
    } else {
      message = "A system error occurred.";
    }
    console.warn(message);
  }
}

但ViewWrappedError已在Angular 4中替换为

export function viewWrappedDebugError(err: any, context: DebugContext): Error {
  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;
}

由于在HttpResponse上调用toString,这使得查询状态代码变得很困难...

我希望angular能够提供一个公共的,受良好支持的API来进行集中式错误处理.除了解析错误消息外,真的没有其他方法可以集中处理HTTP错误吗?

更新:我希望组件可以轻松地覆盖集中式错误处理.

解决方案

另一个选择是简单地拥有一个委派给Http服务的服务,同时添加您需要与之交互的任何自定义错误处理,调试逻辑,额外的标头等API.

然后,该服务成为与Http相关的任何内容进行交互的集中点,因此您可以在此处集中进行错误处理.在我开发的任何项目中,我总会创建这样的类,因为实际上与您交互的每个API都有一些通用配置,每个请求都必须使用该通用配置(即使该配置与指定要使用的基本url一样少).

此类示例:

export class ApiGateway {

  baseURL = "https://myapi.com";  // or sometimes pulled from another file
  constructor(private http: Http) { }

  get(path, params) {
    showLoadingIndicator();

    let headers = this.createMySpecialHeaders();
    let options = { headers: headers } // and whatever else you need to generalize
    let fullUrl = this.baseUrl + path + '?' + this.urlEncode(params)`;
    return this.get(path, params, options)
               .do(() => hideLoadingIndicator())
               .map(res => res.json())
               .catch(err => {
                    hideLoadingIndicator();
                  // show error message or whatever the app does with API errors etc
                  // sometimes rethrow the error, depending on the use case
                })
  }
}

对我来说,这是基本的OOP原则-您将与控件外部的交互包装在适配器类中,以防止外部更改,并在需要时将该外部对象的API更改为您喜欢的东西.

有了这样的类,例如,如果您升级到Angular 4,并且接收错误的方式发生变化,则只有一个地方可以更改以处理新的错误技术.

I want to inform the user if an HTTP request fails, without having to write additional code for every HTTP request.

I had a working prototype for angular 2:

@Injectable()
export class MyErrorHandler extends ErrorHandler {

  constructor() {
    super(false);
  }

  handleError(error: any) {
    this.tellUser(error);
    super.handleError(error);
  }

  tellUser(error: any) {
    // dig for the root cause
    if (error.rejection) {
      error = error.rejection;
    }
    if (error instanceof ViewWrappedError) {
       error = error.originalError;
    }

    let message;
    if (error instanceof Response) {
      // TODO: localize and display nicely
      const messages = {
        0: "Could not connect to server",
      }
      message = messages[error.status] || ("The server reported a system error (HTTP " + error.status + ")");
    } else {
      message = "A system error occurred.";
    }
    console.warn(message);
  }
}

but the ViewWrappedError has been replaced in Angular 4 by

export function viewWrappedDebugError(err: any, context: DebugContext): Error {
  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;
}

Which, by virtue of invoking toString on the HttpResponse, makes it hard to query the status code ...

I'd have expected angular to provide a public, well supported API for centralized error handling. Is there really no way to centrally handle HTTP errors other than parsing error messages?

Update: I'd prefer if a component could easily override the centralized error handling.

解决方案

Another option is simply having a service that delegates to the Http service while adding whatever custom error handling, debugging logic, extra headers etc that you need to interact with your API.

This service then becomes your centralized point for interacting with anything Http related and as such you can centralize your error handling right there. In any project I develop, I ALWAYS create such a class because practically every single API you interact with has some common configuration that has to happen with every request (even if that configuration is as little as specifying the base url to use).

Example of such a class:

export class ApiGateway {

  baseURL = "https://myapi.com";  // or sometimes pulled from another file
  constructor(private http: Http) { }

  get(path, params) {
    showLoadingIndicator();

    let headers = this.createMySpecialHeaders();
    let options = { headers: headers } // and whatever else you need to generalize
    let fullUrl = this.baseUrl + path + '?' + this.urlEncode(params)`;
    return this.get(path, params, options)
               .do(() => hideLoadingIndicator())
               .map(res => res.json())
               .catch(err => {
                    hideLoadingIndicator();
                  // show error message or whatever the app does with API errors etc
                  // sometimes rethrow the error, depending on the use case
                })
  }
}

To me, this is basic OOP principles - you wrap your interactions with things outside your control in an adapter class to allow you some protection against external changes and to change the API of that external thing to something you prefer, if necessary.

With such a class in place, if, for eg, you upgraded to Angular 4 and the means of receiving errors change, you only have one place to change to handle the new error technique.

这篇关于Angular 4中HTTP错误的集中处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆