项目

HTTP错误处理

错误配置

ABP提供如下所示的错误处理配置:

//app.config.ts
import { provideAbpThemeShared } from '@abp/ng.theme.shared';
import { CustomErrorComponent } from './custom-error.component';

export const appConfig: ApplicationConfig = {
  providers: [
    provideAbpThemeShared(
      withHttpErrorConfig({
        skipHandledErrorCodes: [403],
        errorScreen: {
          component: CustomErrorComponent,
          forWhichErrors: [404],
          hideCloseIcon: false,
        },
      }),
    ),
  ],
};
  • ErrorScreenErrorCodes 可传递给 skipHandledErrorCodesforWhichErrors 的错误代码。
  • skipHandledErrorCodes 不希望处理的错误代码。
  • errorScreen 路由错误发生时想要显示的界面。
    • component 想要显示的组件。
    • forWhichErrorsErrorScreenErrorCodes 相同
    • hideCloseIcon 在默认ABP组件中隐藏关闭图标。

自定义HTTP错误处理器

当使用 RestService 时,所有HTTP错误都会报告给 HttpErrorReporterService,然后由 @abp/ng.theme.shared 包暴露的 ErrorHandler 服务自动处理这些错误。

函数方法 已弃用

自定义HTTP错误处理器可以注册到名为 HTTP_ERROR_HANDLER 的注入令牌。如果注册了自定义处理器函数,ErrorHandler 会执行该函数。

查看示例:

// http-error-handler.ts
import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core';
import { ToasterService } from '@abp/ng.theme.shared';
import { HttpErrorResponse } from '@angular/common/http';
import { Injector } from '@angular/core';
import { of, EMPTY } from 'rxjs';
import { Error404Component } from './error404/error404.component';

export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
  if (httpError.status === 400) {
    const toaster = injector.get(ToasterService);
    toaster.error(httpError.error?.error?.message || '请求错误!', '400');
    return EMPTY;
  }

  if (httpError.status === 404) {
    const contentProjection = injector.get(ContentProjectionService);
    contentProjection.projectContent(PROJECTION_STRATEGY.AppendComponentToBody(Error404Component));
    return EMPTY;
  }

  return of(httpError);
}

// app.config.ts
import { Error404Component } from './error404/error404.component';
import { handleHttpErrors } from './http-error-handling';
import { HTTP_ERROR_HANDLER, ... } from '@abp/ng.theme.shared';

export const appConfig: ApplicationConfig = {
  providers: [
    ...
    { provide: HTTP_ERROR_HANDLER, useValue: handleHttpErrors },
    ...
  ],
};

在上面的示例中:

  • 创建了一个名为 handleHttpErrors 的函数,并在 app.config.ts 中定义为 HTTP_ERROR_HANDLER 提供者的值。此后,当HTTP错误发生时,该函数会执行。

  • 处理了400错误请求。当发生400错误时。

  • 由于在 handleHttpErrors 函数底部返回了 of(httpError)ErrorHandler 将处理除400和404错误之外的HTTP错误。

注意1: 如果在处理错误后下一行放置 return EMPTY,默认错误处理将不会对该错误生效。EMPTY 可以从 rxjs 导入。

export function handleHttpErrors(
  injector: Injector,
  httpError: HttpErrorResponse
) {
  if (httpError.status === 403) {
    // 在此处理403错误
    return EMPTY; // 放置 return EMPTY 以跳过默认错误处理
  }
}

注意2: 如果放置 return of(httpError),默认错误处理将会生效。

  • of 是一个函数。可以从 rxjs 导入。
  • httpError 是注册到 HTTP_ERROR_HANDLER 提供者的错误处理器函数的第二个参数。httpError 的类型是 HttpErrorResponse
import { of } from "rxjs";

export function handleHttpErrors(
  injector: Injector,
  httpError: HttpErrorResponse
) {
  if (httpError.status === 500) {
    // 在此处理500错误
  }

  // 可以在函数底部返回 of(httpError),以便对上面未处理的HTTP错误运行ABP的默认处理器。
  return of(httpError);
}

服务方法

您可以使用服务提供多个处理器,自定义HTTP错误处理器服务可以通过名为 CUSTOM_ERROR_HANDLERS 的注入令牌注册。ABP有一些默认的错误处理器

如何添加新的处理器服务

ABP错误处理器服务实现了 CustomHttpErrorHandlerService 接口。

CUSTOM_ERROR_HANDLERS 的接口

interface CustomHttpErrorHandlerService {
  readonly priority: number;
  canHandle(error: unknown): boolean;
  execute(): void;
}
  • priority ABP根据优先级变量的数值对服务进行排序。优先级较高的将首先检查。
  • canHandle 检查服务是否能处理该错误。返回布尔值。
  • execute 如果服务能处理该错误,则运行execute方法。

总结

  • 服务按其优先级数字排序。
  • 从最高优先级的服务开始,运行 canHandle() 方法。如果可以处理错误,则选择该服务;否则检查下一个服务。
  • 如果找到服务,则运行该服务的execute方法。完成。

查看示例:

// custom-error-handler.service.ts
import { inject, Injectable } from "@angular/core";
import { HttpErrorResponse } from "@angular/common/http";
import { CustomHttpErrorHandlerService } from "@abp/ng.theme.shared";
import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from "@abp/ng.theme.shared";
import { ToasterService } from "@abp/ng.theme.shared";

@Injectable({ providedIn: "root" })
export class MyCustomErrorHandlerService
  implements CustomHttpErrorHandlerService
{
  // 您可以在此写入任意数字,例如:9999
  readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.veryHigh;
  protected readonly toaster = inject(ToasterService);
  private error: HttpErrorResponse | undefined = undefined;

  // 此服务应处理何种类型的错误?您可以在该方法中决定。如果错误适合您的情况,则返回true;否则返回false。
  canHandle(error: unknown): boolean {
    if (error instanceof HttpErrorResponse && error.status === 400) {
      this.error = error;
      return true;
    }
    return false;
  }

  // 如果此服务被ErrorHandler选中,将调用此execute方法。
  execute() {
    this.toaster.error(
      this.error.error?.error?.message || "请求错误!",
      "400"
    );
  }
}

// app.config.ts
import { CUSTOM_ERROR_HANDLERS, ... } from '@abp/ng.theme.shared';
import { MyCustomErrorHandlerService } from './custom-error-handler.service';

export const appConfig: ApplicationConfig = {
  providers: [
    //...
    {
      provide: CUSTOM_ERROR_HANDLERS,
      useExisting: MyCustomErrorHandlerService,
      multi: true,
    }
  ],
};

在上面的示例中:

  • 创建了一个名为 MyCustomErrorHandlerService 的服务,并通过 useExisting 键提供,因为我们不希望它的另一个实例。并将 multi 键设置为true,因为ABP默认错误处理器也通过 CUSTOM_ERROR_HANDLERS 注入令牌提供。

  • 400错误由自定义的 MyCustomErrorHandlerService 处理。当发生400错误时,后端错误消息将如下所示显示:

custom-error-handler-toaster-message

注意事项

  • 如果您的服务无法处理该错误,ABP将检查下一个错误服务。
  • 如果没有服务处理该错误,将向用户显示有关错误的基本确认消息。
  • 您可以通过CUSTOM_ERROR_HANDLER注入令牌提供多个服务。
  • 如果您希望自定义服务更早被评估(检查),请将优先级变量设置得较高。
在本文档中