Skip to content

Commit

Permalink
Merge pull request #14182 from nestjs/feat/intrinsic-exception
Browse files Browse the repository at this point in the history
feat(common): introduce intrinsic exception
  • Loading branch information
kamilmysliwiec authored Nov 22, 2024
2 parents 03a61e9 + a077ea5 commit b04895a
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 27 deletions.
11 changes: 8 additions & 3 deletions packages/common/exceptions/http.exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
HttpExceptionBodyMessage,
} from '../interfaces/http/http-exception-body.interface';
import { isNumber, isObject, isString } from '../utils/shared.utils';
import { IntrinsicException } from './intrinsic.exception';

export interface HttpExceptionOptions {
/** original cause of the error */
Expand All @@ -23,7 +24,13 @@ export interface DescriptionAndOptions {
*
* @publicApi
*/
export class HttpException extends Error {
export class HttpException extends IntrinsicException {
/**
* Exception cause. Indicates the specific original cause of the error.
* It is used when catching and re-throwing an error with a more-specific or useful error message in order to still have access to the original error.
*/
public cause: unknown;

/**
* Instantiate a plain HTTP Exception.
*
Expand Down Expand Up @@ -68,8 +75,6 @@ export class HttpException extends Error {
this.initCause();
}

public cause: unknown;

/**
* Configures error chaining support
*
Expand Down
33 changes: 17 additions & 16 deletions packages/common/exceptions/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
export * from './bad-gateway.exception';
export * from './bad-request.exception';
export * from './http.exception';
export * from './unauthorized.exception';
export * from './method-not-allowed.exception';
export * from './not-found.exception';
export * from './forbidden.exception';
export * from './not-acceptable.exception';
export * from './request-timeout.exception';
export * from './conflict.exception';
export * from './forbidden.exception';
export * from './gateway-timeout.exception';
export * from './gone.exception';
export * from './payload-too-large.exception';
export * from './unsupported-media-type.exception';
export * from './unprocessable-entity.exception';
export * from './internal-server-error.exception';
export * from './not-implemented.exception';
export * from './http-version-not-supported.exception';
export * from './bad-gateway.exception';
export * from './service-unavailable.exception';
export * from './gateway-timeout.exception';
export * from './http.exception';
export * from './im-a-teapot.exception';
export * from './precondition-failed.exception';
export * from './internal-server-error.exception';
export * from './intrinsic.exception';
export * from './method-not-allowed.exception';
export * from './misdirected.exception';
export * from './not-acceptable.exception';
export * from './not-found.exception';
export * from './not-implemented.exception';
export * from './payload-too-large.exception';
export * from './precondition-failed.exception';
export * from './request-timeout.exception';
export * from './service-unavailable.exception';
export * from './unauthorized.exception';
export * from './unprocessable-entity.exception';
export * from './unsupported-media-type.exception';
7 changes: 7 additions & 0 deletions packages/common/exceptions/intrinsic.exception.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Exception that represents an intrinsic error in the application.
* When thrown, the default exception filter will not log the error message.
*
* @publicApi
*/
export class IntrinsicException extends Error {}
5 changes: 4 additions & 1 deletion packages/core/exceptions/base-exception-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
HttpServer,
HttpStatus,
Inject,
IntrinsicException,
Logger,
Optional,
} from '@nestjs/common';
Expand Down Expand Up @@ -68,7 +69,9 @@ export class BaseExceptionFilter<T = any> implements ExceptionFilter<T> {
applicationRef.end(response);
}

return BaseExceptionFilter.logger.error(exception);
if (!(exception instanceof IntrinsicException)) {
BaseExceptionFilter.logger.error(exception);
}
}

public isExceptionObject(err: any): err is Error {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/exceptions/external-exception-filter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ArgumentsHost, HttpException, Logger } from '@nestjs/common';
import { ArgumentsHost, IntrinsicException, Logger } from '@nestjs/common';

export class ExternalExceptionFilter<T = any, R = any> {
private static readonly logger = new Logger('ExceptionsHandler');

catch(exception: T, host: ArgumentsHost): R | Promise<R> {
if (exception instanceof Error && !(exception instanceof HttpException)) {
if (
exception instanceof Error &&
!(exception instanceof IntrinsicException)
) {
ExternalExceptionFilter.logger.error(exception);
}
throw exception;
Expand Down
13 changes: 10 additions & 3 deletions packages/microservices/exceptions/base-rpc-exception-filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/* eslint-disable prefer-spread */
import { ArgumentsHost, Logger, RpcExceptionFilter } from '@nestjs/common';
import {
ArgumentsHost,
IntrinsicException,
Logger,
RpcExceptionFilter,
} from '@nestjs/common';
import { isObject } from '@nestjs/common/utils/shared.utils';
import { MESSAGES } from '@nestjs/core/constants';
import { Observable, throwError as _throw } from 'rxjs';
Expand All @@ -26,8 +31,10 @@ export class BaseRpcExceptionFilter<T = any, R = any>
public handleUnknownError(exception: T, status: string) {
const errorMessage = MESSAGES.UNKNOWN_EXCEPTION_MESSAGE;

const logger = BaseRpcExceptionFilter.logger;
logger.error.apply(logger, [exception]);
if (!(exception instanceof IntrinsicException)) {
const logger = BaseRpcExceptionFilter.logger;
logger.error(exception);
}

return _throw(() => ({ status, message: errorMessage }));
}
Expand Down
12 changes: 10 additions & 2 deletions packages/websockets/exceptions/base-ws-exception-filter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ArgumentsHost, Logger, WsExceptionFilter } from '@nestjs/common';
import {
ArgumentsHost,
IntrinsicException,
Logger,
WsExceptionFilter,
} from '@nestjs/common';
import { isObject } from '@nestjs/common/utils/shared.utils';
import { MESSAGES } from '@nestjs/core/constants';
import { WsException } from '../errors/ws-exception';
Expand Down Expand Up @@ -46,7 +51,10 @@ export class BaseWsExceptionFilter<TError = any>
message: MESSAGES.UNKNOWN_EXCEPTION_MESSAGE,
});

return BaseWsExceptionFilter.logger.error(exception);
if (!(exception instanceof IntrinsicException)) {
const logger = BaseWsExceptionFilter.logger;
logger.error(exception);
}
}

public isExceptionObject(err: any): err is Error {
Expand Down

0 comments on commit b04895a

Please sign in to comment.