/** * default-throw.ts — 默认错误抛出实现 * * 基于 schema-adapter 防腐层的 I18nError 联动,实现 app.throw() 的默认行为。 * * 核心流程: * 1. 智能参数识别(第三参数:number → 业务码,object → i18n 插值参数) * 2. 从 requestContext(AsyncLocalStorage)获取当前请求的 locale(并发安全) * 3. 调用 schemaAdapter.createI18nError() 完成 i18n 翻译 + 错误码查找 * 4. 从 I18nError 实例提取翻译结果,构造 HttpError 并抛出 * * 并发安全说明: * defaultThrow 通过 requestContext.getStore()?.locale 获取当前请求的语言, * **不依赖** Locale.currentLocale(全局静态变量,并发请求会互相覆盖)。 * 请求级 locale 由框架内置中间件写入 AsyncLocalStorage(见 06b-error.md §1.7.1)。 * * 业务错误码优先级: * 用户显式传入 code > locale 配置中的 code > 默认使用 status * * @module lib/default-throw * @see 06b-error.md §1.2(内置实现) * @see 06b-error.md §1.1.1(schema-dsl 与 vext 的依赖方向) * @see IMPLEMENTATION-PLAN.md 任务 1.8 */ export interface VextThrowOptions { status: number; message: string; params?: Record; code?: number | string; details?: unknown; } /** * VextThrowFn — app.throw 的函数签名 * * 支持三种调用形式: * - app.throw(messageKey) — i18n key 快捷方式(status 从 i18n 配置读取,默认 400) * - app.throw(messageKey, params?) — i18n key + 插值参数(status 从 i18n 配置读取,默认 400) * - app.throw(status, message, code?) — 原始文本 + 可选业务码 * - app.throw(status, message, params?, code?) — i18n key + 插值参数 + 可选业务码 * - app.throw(status, message, params?, details) — 第四参 object/array 作为业务 details * - app.throw({ status, message, params, code, details }) — 完整入口 */ export type VextThrowFn = { (messageKey: string): never; (messageKey: string, params: Record): never; (options: VextThrowOptions): never; (status: number, message: string, code?: number | string): never; (status: number, message: string, params?: Record | number | string, codeOrDetails?: number | string | unknown[] | Record): never; }; /** * 创建默认的 app.throw 实现 * * 返回一个闭包函数,内部通过 schema-adapter 防腐层访问 schema-dsl, * 完成 i18n 翻译后构造 HttpError 抛出。 * * 之所以是工厂函数而非直接导出函数,是为了: * 1. 未来可能需要注入依赖(如 logger) * 2. 与 app.setThrow(wrapper) 的 wrapper 模式对齐 * 3. 测试时可方便地创建独立实例 * * @returns defaultThrow 函数 * * @example * ```typescript * import { createDefaultThrow } from './default-throw.js' * * const defaultThrow = createDefaultThrow() * * // i18n key * defaultThrow(404, 'user.not_found') * * // 原始文本 + 业务码 * defaultThrow(400, '邮箱已注册', 10001) * * // i18n key + 参数插值 * defaultThrow(400, 'balance.insufficient', { balance: 50, required: 100 }) * * // i18n key + 参数 + 业务码 * defaultThrow(400, 'balance.insufficient', { balance: 50 }, 50001) * ``` */ export declare function createDefaultThrow(): VextThrowFn;