Kind: Class
Source: packages/core/exceptions/exceptions-handler.ts
Part of: Core
ExceptionsHandler coordinates exception processing for a request or execution context. It first attempts to match and invoke registered custom exception filters, then falls back to the base exception filter when no custom filter handles the error.
Extends: BaseExceptionFilter
Methods
| Method | Signature | Returns |
|---|---|---|
next | `next(exception: Error | HttpException, ctx: ArgumentsHost)` |
setCustomFilters | setCustomFilters(filters: ExceptionFilterMetadata[]) | void |
invokeCustomFilters | invokeCustomFilters(exception: T, ctx: ArgumentsHost) | boolean |
Where it refuses work
ExceptionsHandlerstops the work withInvalidExceptionFilterExceptionwhen!Array.isArray(filters).ExceptionsHandlerstops the work with an early return whenthis.invokeCustomFilters(exception, ctx).ExceptionsHandlerstops the work with an early return whenisEmpty(this.filters).
Diagram
mermaidgraph LR A[Exception thrown] --> B[ExceptionsHandler.next] B --> C{Custom filter matches?} C -->|Yes| D[invokeCustomFilters] D --> E[Custom filter response] C -->|No| F[BaseExceptionFilter.catch] F --> G[Default error response]
Usage
tsimport { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';
import { ExceptionsHandler } from '@nestjs/core/exceptions/exceptions-handler';
class DomainError extends Error {}
@Catch(DomainError)
class DomainErrorFilter implements ExceptionFilter {
catch(exception: DomainError, host: ArgumentsHost) {
const response = host.switchToHttp().getResponse();
response.status(400).json({
statusCode: 400,
message: exception.message,
});
}
}
const { httpAdapter } = app.get(HttpAdapterHost);
const exceptionsHandler = new ExceptionsHandler(httpAdapter);
const filter = new DomainErrorFilter();
exceptionsHandler.setCustomFilters([
{
exceptionMetatypes: [DomainError],
func: filter.catch.bind(filter),
},
]);
// Typically called internally by Nest when an exception occurs.
exceptionsHandler.next(new DomainError('Invalid domain input'), argumentsHost);
AI Coding Instructions
- Register custom filters through
setCustomFilters()usingexceptionMetatypesand a correctly boundfunccallback. - Call
next()to preserve the normal handling flow; it invokes matching custom filters before using the default exception response behavior. - Ensure custom filter callbacks preserve their
thiscontext, such as withfilter.catch.bind(filter). - Return control from a custom filter only after writing an appropriate response for the active transport context.
- Treat
ExceptionsHandleras framework infrastructure; prefer Nest’s@UseFilters()and@Catch()APIs for most application-level exception handling.
How it works
-
ExceptionsHandleris an exported HTTP exception handler that extendsBaseExceptionFilter. It keeps a private array of customExceptionFilterMetadata, initially empty. [packages/core/exceptions/exceptions-handler.ts:9-10] -
next(exception, ctx)first attempts custom-filter handling. If a matching custom filter is found, it returns without invoking the inherited fallback; otherwise, it callsBaseExceptionFilter.catch(exception, ctx). [packages/core/exceptions/exceptions-handler.ts:12-17] -
The fallback treats
HttpExceptioninstances differently from other values: it obtains the exception response, sends it through the HTTP adapter when headers have not already been sent, or ends the response otherwise. [packages/core/exceptions/base-exception-filter.ts:26-47] For non-HttpExceptionvalues, it sends either an error object’sstatusCodeandmessage, or a 500 response with the unknown-exception message; it logs non-IntrinsicExceptionvalues. [packages/core/exceptions/base-exception-filter.ts:50-75] -
setCustomFilters(filters)requiresfiltersto be an array. A non-array value throwsInvalidExceptionFilterException; an array replaces the handler’s current filter array. [packages/core/exceptions/exceptions-handler.ts:19-24] That exception extendsRuntimeExceptionand has the messageInvalid exception filters (@UseFilters()).. [packages/core/errors/exceptions/invalid-exception-filter.exception.ts:4-7] [packages/core/errors/messages.ts:262] -
invokeCustomFilters(exception, ctx)returnsfalsewhen its filter array has no elements. [packages/core/exceptions/exceptions-handler.ts:26-32] Otherwise, it selects the first metadata entry whoseexceptionMetatypesarray is empty or contains a type for whichexception instanceof ExceptionMetaTypeis true. [packages/common/utils/select-exception-filter-metadata.util.ts:3-13] When selected, it calls that entry’sfunc(exception, ctx)and returnstrue; when none match, it returnsfalse. [packages/core/exceptions/exceptions-handler.ts:34-36] -
Each filter metadata entry contains a
funccallback typed as an exception filter’scatchmethod and anexceptionMetatypesarray. [packages/common/interfaces/exceptions/exception-filter-metadata.interface.ts:4-7] Filter contexts create these entries by binding an instantiated filter’scatchmethod and reading its reflected caught-exception metadata. [packages/core/exceptions/base-exception-filter-context.ts:26-36] [packages/core/exceptions/base-exception-filter-context.ts:73-77] -
In HTTP route setup,
RouterExceptionFilters.createconstructsExceptionsHandlerwith the HTTP server adapter. If filters exist, it reverses their order before passing them tosetCustomFilters. [packages/core/router/router-exception-filters.ts:23-44]RouterProxycallsnextafter a route callback or exception-layer callback throws, passing anExecutionContextHostcontaining request, response, andnext. [packages/core/router/router-proxy.ts:20-26] [packages/core/router/router-proxy.ts:45-51]
Relationships
- IMPORTS →
HttpException - IMPORTS →
ExceptionFilterMetadata - IMPORTS →
ArgumentsHost - IMPORTS →
selectExceptionFilterMetadata - IMPORTS →
isEmpty
Was this page helpful?