import { ValidationError } from 'class-validator'; import { NormalizedErrorDto } from '../dto/normalized-error.dto'; export interface ValidationFieldError { field: string; constraints: string[]; } export function flattenValidationErrors( errors: ValidationError[], parentPath = '', ): ValidationFieldError[] { const result: ValidationFieldError[] = []; for (const error of errors) { const field = parentPath ? `${parentPath}.${error.property}` : error.property; if (error.constraints) { result.push({ field, constraints: Object.values(error.constraints), }); } if (error.children?.length) { result.push(...flattenValidationErrors(error.children, field)); } } return result; } export function buildValidationErrorResponse(errors: ValidationError[]): { normalizedError: NormalizedErrorDto; details: ValidationFieldError[]; } { const details = flattenValidationErrors(errors); const summary = details.length > 0 ? details.map((d) => `${d.field}: ${d.constraints.join(', ')}`).join('; ') : 'Request validation failed'; return { normalizedError: { code: 'VALIDATION_ERROR', message: summary, details, }, details, }; } export function formatHttpExceptionMessage(exception: unknown): string { if (!(exception && typeof exception === 'object' && 'getResponse' in exception)) { return exception instanceof Error ? exception.message : String(exception); } const response = (exception as { getResponse: () => unknown }).getResponse(); if (typeof response === 'string') { return response; } if (typeof response !== 'object' || response === null) { return exception instanceof Error ? exception.message : 'Request failed'; } const body = response as { message?: string | string[]; error?: unknown; }; if (isNormalizedError(body.error)) { return body.error.message; } if (Array.isArray(body.message)) { return body.message.join('; '); } if (typeof body.message === 'string' && body.message.length > 0) { return body.message; } return exception instanceof Error ? exception.message : 'Request failed'; } export function isNormalizedError(value: unknown): value is NormalizedErrorDto { return ( typeof value === 'object' && value !== null && 'code' in value && 'message' in value && typeof (value as NormalizedErrorDto).code === 'string' && typeof (value as NormalizedErrorDto).message === 'string' ); }