All files / src/platform/gateway/filters api-error-mapping.filter.ts

0% Statements 0/44
0% Branches 0/26
0% Functions 0/1
0% Lines 0/42

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                                                                                                                                                   
import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { AppException } from '../../../common/errors/app.exception';
import { ErrorCode } from '../../../common/errors/error-codes.enum';
 
@Catch()
export class ApiErrorMappingFilter implements ExceptionFilter {
  private readonly logger = new Logger(ApiErrorMappingFilter.name);
 
  catch(exception: unknown, host: ArgumentsHost): void {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
 
    const req = request as any;
    const requestId: string = req.requestId || 'unknown';
    const correlationId: string = req.correlationId || 'unknown';
 
    let status = HttpStatus.INTERNAL_SERVER_ERROR;
    let code: ErrorCode = ErrorCode.INTERNAL_ERROR;
    let message = 'An unexpected error occurred';
    let details: any[] = [];
    let fieldErrors: Record<string, string> = {};
 
    if (exception instanceof AppException) {
      status = exception.getStatus();
      code = exception.code;
      const body = exception.getResponse() as any;
      message = body?.error?.message ?? message;
      details = exception.details;
      fieldErrors = exception.fieldErrors;
    } else if (exception instanceof HttpException) {
      status = exception.getStatus();
      const body = exception.getResponse() as any;
      message = typeof body === 'string' ? body : (body.message ?? message);
      if (Array.isArray(body.message)) {
        details = body.message;
        message = 'Validation failed';
        code = ErrorCode.VALIDATION_ERROR;
      } else if (status === HttpStatus.NOT_FOUND) {
        code = ErrorCode.NOT_FOUND;
      } else if (status === HttpStatus.UNAUTHORIZED) {
        code = ErrorCode.UNAUTHORIZED;
      } else if (status === HttpStatus.FORBIDDEN) {
        code = ErrorCode.FORBIDDEN;
      } else if (status === HttpStatus.TOO_MANY_REQUESTS) {
        code = ErrorCode.RATE_LIMIT_EXCEEDED;
      }
    } else if (exception instanceof Error) {
      this.logger.error(
        `Unhandled exception: ${exception.message}`,
        exception.stack,
      );
    }
 
    response.status(status).json({
      success: false,
      error: { code, message, details, fieldErrors },
      meta: {
        requestId,
        correlationId,
        timestamp: new Date().toISOString(),
      },
    });
  }
}