All files / src http-exception.filter.ts

86.2% Statements 25/29
78.94% Branches 15/19
100% Functions 2/2
85.18% Lines 23/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 866x                     6x 6x     33x 33x 33x     33x       33x 33x     33x 32x 32x   32x       32x           32x     32x 3x   32x   32x             1x               1x             33x                   33x      
import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
 
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  private readonly logger = new Logger(AllExceptionsFilter.name);
 
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
 
    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;
 
    let message = 'Internal server error';
    let code = 'INTERNAL_SERVER_ERROR';
    let details: any;
 
    if (exception instanceof HttpException) {
      const exceptionResponse = exception.getResponse();
      Iif (typeof exceptionResponse === 'string') {
        message = exceptionResponse;
      } else if (
        typeof exceptionResponse === 'object' &&
        exceptionResponse !== null
      ) {
        const res = exceptionResponse as {
          message: any;
          error?: string;
          statusCode?: number;
        };
        // For class-validator errors, message is an array of strings.
        message = Array.isArray(res.message)
          ? res.message.join(', ')
          : res.message;
        if (Array.isArray(res.message) && res.message.length > 0) {
          details = res.message;
        }
        code = res.error?.replace(/\s/g, '_').toUpperCase() || 'HTTP_EXCEPTION';
      }
      Iif (status >= 500) {
        this.logger.error(
          `HTTP Exception: ${message}`,
          exception.stack,
          `${request.method} ${request.url}`,
        );
      }
    } else Iif (exception instanceof Error) {
      message = exception.message;
      this.logger.error(
        `Unhandled Exception: ${message}`,
        exception.stack,
        `${request.method} ${request.url}`,
      );
    } else {
      this.logger.error(
        `Unhandled unknown exception type`,
        exception,
        `${request.method} ${request.url}`,
      );
    }
 
    const errorResponsePayload = {
      error: {
        code: code,
        message: message,
        details: details,
        timestamp: new Date().toISOString(),
        path: request.url,
      },
    };
 
    response.status(status).json(errorResponsePayload);
  }
}