// Проброс ошибок из вышестоящего API наружу. // // Панель, которая ходит за данными в основной API продукта, должна отдать // клиенту его статус и текст, а не превратить всё в 500: «пользователь не // найден» и «API лежит» — разные ситуации для оператора. // // Форма ошибки axios здесь проверяется по структуре, а не через // axios.isAxiosError: ядру не нужна зависимость от axios ради одной проверки, // а панель может ходить наверх и через fetch. import type { Response } from 'express'; interface UpstreamError { response?: { status?: number; data?: { message?: string; error?: string }; }; } export interface ForwardErrorOptions { /** Текст, когда вышестоящий API недоступен вовсе. */ unavailable?: string; /** Текст, когда API ответил ошибкой без внятного сообщения. */ fallback?: string; } export function forwardError(res: Response, error: unknown, options: ForwardErrorOptions = {}) { const unavailable = options.unavailable ?? 'Вышестоящий API недоступен'; const fallback = options.fallback ?? 'Ошибка API'; const response = (error as UpstreamError)?.response; if (response && typeof response.status === 'number') { const data = response.data; res.status(response.status).json({ message: data?.message ?? data?.error ?? fallback }); return; } res.status(502).json({ message: unavailable }); }