solver-sdk
Version:
SDK for WorkAI API - AI-powered code analysis with WorkCoins billing system
147 lines • 6.38 kB
JavaScript
/**
* Централизованный маппер ошибок
* Преобразует Axios errors в типизированные SDK исключения
*/
import { AuthenticationError, ForbiddenError, ValidationError, NotFoundError, ConflictError, BadRequestError, InternalServerError, ServiceUnavailableError, GatewayTimeoutError, DatabaseError, TimeoutError, NetworkError, LimitExceededError, RateLimitError, BaseSDKError, } from '../errors/sdk-errors.js';
/**
* Класс для маппинга HTTP ошибок на типизированные исключения SDK
*/
export class ErrorMapper {
/**
* Маппит Axios error на типизированное SDK исключение
* @param axiosError Ошибка от Axios
* @returns Типизированное исключение SDK
*/
static mapError(axiosError) {
const response = axiosError.response;
// 1. Network errors (нет ответа от сервера)
if (!response) {
return new NetworkError(axiosError.message || 'Network error occurred', { originalError: axiosError });
}
const status = response.status;
const data = response.data || {};
// Извлекаем errorType из backend response
// Backend структура: { success: false, error: { type, message, code }, requestId, timestamp }
const errorType = data.error?.type || this.inferErrorType(status);
const message = data.error?.message || data.message || axiosError.message || 'Unknown error';
const details = {
...data,
originalError: axiosError,
};
// 2. Специальные случаи (приоритет - проверяем первыми)
// LimitExceededError: 403 + credits_limit_exceeded
// Backend отправляет: { success: false, error: { type, message, details: { balance, action, plan } } }
if (status === 403 && errorType === 'credits_limit_exceeded') {
// Передаем data.error, т.к. LimitExceededError ожидает { message, details }
return new LimitExceededError(data.error || data);
}
// RateLimitError: 429
if (status === 429) {
return new RateLimitError(data.error || data);
}
// 3. Маппинг по errorType из backend
switch (errorType) {
case 'unauthorized':
return new AuthenticationError(message, details);
case 'forbidden':
return new ForbiddenError(message, details);
case 'validation_error':
return new ValidationError(message, details);
case 'not_found':
return new NotFoundError(message, details);
case 'conflict':
return new ConflictError(message, details);
case 'bad_request':
return new BadRequestError(message, details);
case 'database_error':
return new DatabaseError(message, details);
case 'timeout_error':
case 'gateway_timeout':
return new TimeoutError(message, details);
case 'internal_server_error':
case 'server_error':
return new InternalServerError(message, details);
case 'service_unavailable':
return new ServiceUnavailableError(message, details);
case 'rate_limit_exceeded':
return new RateLimitError(data.error || data);
case 'credits_limit_exceeded':
return new LimitExceededError(data.error || data);
default:
// 4. Fallback по HTTP статусу
return this.mapByStatusCode(status, message, details);
}
}
/**
* Определяет тип ошибки по HTTP статусу (fallback)
*/
static inferErrorType(status) {
if (status === 401)
return 'unauthorized';
if (status === 403)
return 'forbidden';
if (status === 404)
return 'not_found';
if (status === 422)
return 'validation_error';
if (status === 409)
return 'conflict';
if (status === 400)
return 'bad_request';
if (status === 429)
return 'rate_limit_exceeded';
if (status === 408)
return 'timeout_error';
if (status === 503)
return 'service_unavailable';
if (status === 504)
return 'gateway_timeout';
if (status >= 500)
return 'internal_server_error';
return 'unknown_error';
}
/**
* Маппит ошибку по HTTP статусу (fallback когда errorType неизвестен)
*/
static mapByStatusCode(status, message, details) {
// 4xx Client Errors
if (status === 401) {
return new AuthenticationError(message, details);
}
if (status === 403) {
return new ForbiddenError(message, details);
}
if (status === 404) {
return new NotFoundError(message, details);
}
if (status === 422) {
return new ValidationError(message, details);
}
if (status === 409) {
return new ConflictError(message, details);
}
if (status === 400) {
return new BadRequestError(message, details);
}
if (status === 408) {
return new TimeoutError(message, details);
}
if (status === 429) {
// В details уже есть все данные response (включая error если есть)
return new RateLimitError(details.error || details);
}
// 5xx Server Errors
if (status === 503) {
return new ServiceUnavailableError(message, details);
}
if (status === 504) {
return new GatewayTimeoutError(message, details);
}
if (status >= 500) {
return new InternalServerError(message, details);
}
// Unknown error - возвращаем базовый класс
return new BaseSDKError(status, 'unknown_error', message, details);
}
}
//# sourceMappingURL=error-mapper.js.map