92 lines
2.4 KiB
TypeScript
92 lines
2.4 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { ErrorCode, ErrorMessages } from '../constants/error-codes';
|
|
import { ErrorResponseDto } from '../dtos/error-response.dto';
|
|
|
|
export type SupportedLocale = 'en-US' | 'es-ES' | 'fr-FR' | 'pt-BR' | 'zh-CN';
|
|
|
|
@Injectable()
|
|
export class ErrorResponseService {
|
|
private defaultLocale: SupportedLocale = 'en-US';
|
|
|
|
/**
|
|
* Get localized error message
|
|
*/
|
|
getErrorMessage(code: ErrorCode, locale?: SupportedLocale): string {
|
|
const normalizedLocale = locale || this.defaultLocale;
|
|
const messages = ErrorMessages[code];
|
|
|
|
if (!messages) {
|
|
return 'An unexpected error occurred';
|
|
}
|
|
|
|
return messages[normalizedLocale] || messages[this.defaultLocale];
|
|
}
|
|
|
|
/**
|
|
* Create error response DTO
|
|
*/
|
|
createErrorResponse(
|
|
code: ErrorCode,
|
|
statusCode: number,
|
|
locale?: SupportedLocale,
|
|
path?: string,
|
|
details?: any,
|
|
): ErrorResponseDto {
|
|
const message = this.getErrorMessage(code, locale);
|
|
return new ErrorResponseDto(code, message, statusCode, path, details);
|
|
}
|
|
|
|
/**
|
|
* Extract locale from request headers
|
|
*/
|
|
extractLocale(acceptLanguage?: string): SupportedLocale {
|
|
if (!acceptLanguage) {
|
|
return this.defaultLocale;
|
|
}
|
|
|
|
// Parse Accept-Language header (e.g., "en-US,en;q=0.9,es;q=0.8")
|
|
const locales = acceptLanguage.split(',').map((lang) => {
|
|
const [locale] = lang.trim().split(';');
|
|
return locale;
|
|
});
|
|
|
|
// Find first supported locale
|
|
for (const locale of locales) {
|
|
if (this.isSupportedLocale(locale)) {
|
|
return locale as SupportedLocale;
|
|
}
|
|
|
|
// Try matching language code only (e.g., "en" -> "en-US")
|
|
const languageCode = locale.split('-')[0];
|
|
const matchedLocale = this.findLocaleByLanguage(languageCode);
|
|
if (matchedLocale) {
|
|
return matchedLocale;
|
|
}
|
|
}
|
|
|
|
return this.defaultLocale;
|
|
}
|
|
|
|
/**
|
|
* Check if locale is supported
|
|
*/
|
|
private isSupportedLocale(locale: string): boolean {
|
|
return ['en-US', 'es-ES', 'fr-FR', 'pt-BR', 'zh-CN'].includes(locale);
|
|
}
|
|
|
|
/**
|
|
* Find locale by language code
|
|
*/
|
|
private findLocaleByLanguage(languageCode: string): SupportedLocale | null {
|
|
const localeMap: Record<string, SupportedLocale> = {
|
|
en: 'en-US',
|
|
es: 'es-ES',
|
|
fr: 'fr-FR',
|
|
pt: 'pt-BR',
|
|
zh: 'zh-CN',
|
|
};
|
|
|
|
return localeMap[languageCode] || null;
|
|
}
|
|
}
|