Skip to content

HTTP error handling ​

The transport reports failed requests; theme-shared decides how they appear. Basic Theme registers the default chain. Keep transport handling, form errors and application notifications in their respective layers.

Default handler order ​

Smaller priority numbers run first. The first matching handler takes the error.

PriorityHandlerEffect
10AuthenticationErrorHandlerSends a supported 401 to the authentication flow
20TenantResolveErrorHandlerReports a tenant resolution failure and clears the selection
30ValidationErrorHandlerSends validation errors to an active registered form
40AbpFormatErrorHandlerShows the ABP envelope, using a dialog when details exist
50StatusCodeErrorHandlerShows the error page for supported HTTP statuses
99UnknownStatusCodeErrorHandlerHandles the remaining errors

A validation response is also an ABP envelope. The form handler precedes the envelope handler and only claims the response when a form is listening. Otherwise the user still sees the server message.

Add a handler ​

Create src/rate-limit-handler.ts with the following content:

ts
import { defineService, inject } from '@lsw-abpvue/core';
import {
  provideErrorHandler,
  ToasterService,
  type AbpErrorHandler,
} from '@lsw-abpvue/theme-shared';

export const RateLimitHandler = defineService<AbpErrorHandler>('RateLimitHandler', () => {
  const toaster = inject(ToasterService);
  return {
    priority: 35,
    canHandle: error => error.status === 429,
    handle: error => {
      toaster.warn({
        key: 'BookStore::RateLimited',
        defaultValue: error.error?.message ?? 'Too many requests. Try again later.',
      });
    },
  };
});

export const rateLimitProvider = provideErrorHandler(RateLimitHandler);

The handler deals with HTTP 429 at priority 35, after form validation and before the generic envelope. It resolves its dependencies during construction; the later callback uses captured services.

Add its provider to the application's existing providers:

ts
import { rateLimitProvider } from './rate-limit-handler';

const providers = [
  // Existing core, router, OAuth and theme providers...
  rateLimitProvider,
];

Supply this array to createAbpApp. Register the handler at root scope before startup resolves the chain. Adding a provider in a later child injector does not rebuild an already initialized root chain.

canHandle must be narrow. A handler returning true for every error prevents all later handlers from running. handle can return a Promise; returning from it does not resume the chain.

Handle one request locally ​

ts
import { AbpHttpError, inject, RestService } from '@lsw-abpvue/core';

const rest = inject(RestService);
async function saveName(name: string): Promise<string | undefined> {
  try {
    await rest.request<{ name: string }, unknown>(
      { method: 'POST', url: '/api/app/product', body: { name } },
      { skipHandleError: true },
    );
    return undefined;
  } catch (error) {
    if (error instanceof AbpHttpError) return error.error?.message ?? 'Save failed';
    throw error;
  }
}

The caller must display the returned message. skipHandleError suppresses all global reporting for this request, including automatic field-error dispatch; attach field messages yourself if needed. It does not convert a rejection into success.

Error pages ​

ErrorPageService.show({ status, title, details, showHome }) sets the shared error-page state; clear() removes it. Basic Theme renders that state in its layout. A custom layout must include its own error rendering. Resolve the service before entering asynchronous callbacks.

Use provideErrorHandler to register a typed AbpErrorHandler. Its canHandle(error) selects the request and handle(error) decides the feedback. Check handled, unhandled and validation failures after changing the chain.

Check the result ​

Trigger the endpoint's actual 429 response and verify one notification appears. Verify a 400 with field errors still reaches the form and a 401 still reaches authentication. The status code alone does not identify an ABP business error; inspect the envelope and headers when designing a predicate.

Unofficial community project. MIT licensed. Not affiliated with Volosoft.