37 lines
2.1 KiB
TypeScript
37 lines
2.1 KiB
TypeScript
import { t } from '#/locales/t';
|
||
|
||
/** Convert API errors to text without rendering objects or echoing request inputs. */
|
||
function errorText(value: unknown, depth = 0): string {
|
||
// Backend messages are shown as-is; t() only swaps in an English text when the dictionary has one.
|
||
if (typeof value === 'string') return t(value.trim());
|
||
if (!value || typeof value !== 'object' || depth > 3) return '';
|
||
if (Array.isArray(value)) {
|
||
return [...new Set(value.slice(0, 3).map((entry) => errorText(entry, depth + 1)).filter(Boolean))].join(t(';'));
|
||
}
|
||
const detail = value as Record<string, unknown>;
|
||
if (Array.isArray(detail.loc) && typeof detail.type === 'string') {
|
||
const field = detail.loc.at(-1) === 'query' ? t('检索问题') : t('请求参数');
|
||
const ctx = detail.ctx as Record<string, unknown> | undefined;
|
||
if (detail.type === 'string_too_short' && typeof ctx?.min_length === 'number') return t('{field}至少需要 {min} 个字符', { field, min: ctx.min_length });
|
||
if (detail.type === 'string_too_long' && typeof ctx?.max_length === 'number') return t('{field}不能超过 {max} 个字符', { field, max: ctx.max_length });
|
||
if (detail.type === 'missing') return t('请填写{field}', { field });
|
||
if (detail.type === 'string_type') return t('{field}必须是文本', { field });
|
||
return typeof detail.msg === 'string' ? t('{field}:{msg}', { field, msg: detail.msg }) : t('{field}格式不正确', { field });
|
||
}
|
||
for (const key of ['detail', 'error', 'message', 'msg']) {
|
||
const text = errorText(detail[key], depth + 1);
|
||
if (text) return text;
|
||
}
|
||
return '';
|
||
}
|
||
|
||
export function responseErrorMessage(data: unknown, fallback = t('请求失败,请稍后重试')): string {
|
||
return errorText(data) || fallback;
|
||
}
|
||
|
||
export function requestErrorMessage(error: unknown, fallback = t('请求失败,请稍后重试')): string {
|
||
const data = (error as { response?: { data?: unknown } } | null)?.response?.data;
|
||
// RequestClient unwraps Axios response.data before rejecting to page handlers.
|
||
return responseErrorMessage(data ?? (error instanceof Error ? undefined : error), fallback);
|
||
}
|