Kind: Class
Source: packages/microservices/exceptions/rpc-exceptions-handler.ts
Part of: Microservices
RpcExceptionsHandler handles exceptions raised while processing microservice RPC requests. It first attempts to delegate errors to registered custom RPC exception filters, then falls back to the framework's default RPC exception handling behavior when no filter applies.
Extends: BaseRpcExceptionFilter
Methods
| Method | Signature | Returns |
|---|---|---|
handle | `handle(exception: Error | RpcException, host: ArgumentsHost)` |
setCustomFilters | setCustomFilters(filters: RpcExceptionFilterMetadata[]) | void |
invokeCustomFilters | invokeCustomFilters(exception: T, host: ArgumentsHost) | `Observable |
Where it refuses work
RpcExceptionsHandlerstops the work withInvalidExceptionFilterExceptionwhen!Array.isArray(filters).RpcExceptionsHandlerstops the work with an early return whenfilterResult$.RpcExceptionsHandlerstops the work with an early return whenisEmpty(this.filters).
Diagram
mermaidgraph LR A[RPC handler throws exception] --> B[RpcExceptionsHandler.handle] B --> C[invokeCustomFilters] C -->|Matching filter found| D[Custom RPC exception filter] C -->|No matching filter| E[BaseRpcExceptionFilter.catch] D --> F[Observable RPC error response] E --> F
Usage
tsimport { RpcExceptionsHandler } from '@nestjs/microservices';
import { RpcException } from '@nestjs/microservices';
import { Observable, throwError } from 'rxjs';
const exceptionsHandler = new RpcExceptionsHandler();
exceptionsHandler.setCustomFilters([
{
catch(exception: Error): Observable<never> {
console.error('RPC error:', exception.message);
return throwError(
() => new RpcException('A service-specific error occurred'),
);
},
},
]);
const response$ = exceptionsHandler.handle(
new Error('Unable to process payment'),
);
response$.subscribe({
error: error => console.error(error),
});
AI Coding Instructions
- Register custom filters through
setCustomFilters()when a microservice needs transport- or domain-specific error responses. - Ensure custom filters return an
Observable; RPC exception handling is asynchronous and must preserve the observable contract. - Let
handle()remain the main entry point so custom filters are evaluated before default exception serialization. - Make custom filters target specific exception types where possible to avoid unintentionally handling unrelated RPC errors.
- Keep fallback behavior intact: if
invokeCustomFilters()returnsnull, delegate to the base RPC exception handler.
How it works
-
RpcExceptionsHandleris an exported public class that extendsBaseRpcExceptionFilter. It maintains a private array of RPC exception-filter metadata, initially empty. [packages/microservices/exceptions/rpc-exceptions-handler.ts:10-14] -
handle(exception, host)first callsinvokeCustomFilters. If that call returns a truthy observable,handlereturns it; otherwise it delegates to the inheritedcatch(exception, host)method. Its declared inputs are anErrororRpcExceptionand anArgumentsHost, and its declared return type isObservable<any>. [packages/microservices/exceptions/rpc-exceptions-handler.ts:16-25] -
A configured filter is selected only when its
exceptionMetatypesarray is empty or the thrown value is aninstanceofat least one listed metatype. Selection usesfind, so only the first matching metadata entry is invoked. The selected entry’sfuncis called with(exception, host)and its observable is returned. [packages/microservices/exceptions/rpc-exceptions-handler.ts:34-44] [packages/common/utils/select-exception-filter-metadata.util.ts:3-13] The metadata contract consists of a filtercatchfunction and an array of exception metatypes; that function returns an observable. [packages/common/interfaces/exceptions/rpc-exception-filter-metadata.interface.ts:4-7] [packages/common/interfaces/exceptions/rpc-exception-filter.interface.ts:11-19] -
If no filters have been set, or the stored array has no items,
invokeCustomFiltersreturnsnull. It also returnsnullwhen no configured filter matches, causinghandleto use inherited handling. [packages/microservices/exceptions/rpc-exceptions-handler.ts:38-43] [packages/common/utils/shared.utils.ts:48-50] -
setCustomFilters(filters)requires its runtime argument to be an array. A non-array throwsInvalidExceptionFilterException; an array replaces the handler’s stored filter array. [packages/microservices/exceptions/rpc-exceptions-handler.ts:27-32] That exception extendsRuntimeExceptionand is initialized with the messageInvalid exception filters (@UseFilters()).. [packages/core/errors/exceptions/invalid-exception-filter.exception.ts:4-7] [packages/core/errors/messages.ts:260-263] -
In the inherited fallback, a
RpcExceptionproduces an RxJS error observable: ifgetError()returns an object, that object is emitted as the error; otherwise the emitted error is{ status: 'error', message: <getError result> }. [packages/microservices/exceptions/base-rpc-exception-filter.ts:21-29] An exception that is not aRpcExceptionproduces an error observable with{ status: 'error', message: 'Internal server error' }; it is logged unless it is anIntrinsicException. [packages/microservices/exceptions/base-rpc-exception-filter.ts:31-40] [packages/core/constants.ts:5-8] -
In the microservices execution path,
ExceptionFiltersContext.createinstantiates this handler, builds filter metadata for a controller callback, and, when that set is non-empty, stores the reversed array throughsetCustomFilters. [packages/microservices/context/exception-filters-context.ts:24-45]RpcProxysends both rejected observables and thrown callback errors tohandle, creating anExecutionContextHostfrom the call arguments and marking its type asrpc. [packages/microservices/context/rpc-proxy.ts:11-23] [packages/microservices/context/rpc-proxy.ts:27-35]
Relationships
- IMPORTS →
RpcExceptionFilterMetadata - IMPORTS →
ArgumentsHost - IMPORTS →
selectExceptionFilterMetadata - IMPORTS →
isEmpty - IMPORTS →
InvalidExceptionFilterException
Was this page helpful?