48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
/**
|
||
* 共享的后端 envelope 解析工具
|
||
*
|
||
* 4 个 `*_api.ts` 文件中重复的 `interface ApiEnvelope<T>` 与 `function unwrap<T>`
|
||
* 集中到这里。HTTP 拦截器(`http_client.ts`)已经对非 2xx 响应抛 `ApiError`;
|
||
* 本工具处理第二种失败:2xx 但 `success: false` 的 envelope。
|
||
*
|
||
* 失败时仍抛 `ApiError`,让底层保留 HTTP/API 上下文;进入仓库层 `Result`
|
||
* 后会被 `ExceptionHandler` 统一收敛为应用可消费的 `{ code, message }`。
|
||
*/
|
||
import { ApiError, ErrorCode } from "./api_result";
|
||
|
||
/** 后端统一响应包装。 */
|
||
export interface ApiEnvelope<T> {
|
||
success: boolean;
|
||
data?: T;
|
||
message?: string;
|
||
error?: string;
|
||
}
|
||
|
||
/**
|
||
* 解包 envelope,失败时抛 `ApiError`。
|
||
* 用于:data 字段必有(API 一定返回业务数据)的端点。
|
||
*/
|
||
export function unwrap<T>(envelope: ApiEnvelope<T>): T {
|
||
if (!envelope.success || envelope.data === undefined) {
|
||
throw new ApiError(
|
||
ErrorCode.unknownError,
|
||
envelope.message ?? envelope.error ?? "API call failed",
|
||
);
|
||
}
|
||
return envelope.data;
|
||
}
|
||
|
||
/**
|
||
* 解包 envelope,但允许 `data` 字段为 `undefined`(用于 fire-and-forget 类端点)。
|
||
* 失败时仍抛 `ApiError`。
|
||
*/
|
||
export function unwrapOptional<T>(envelope: ApiEnvelope<T>): T | undefined {
|
||
if (!envelope.success) {
|
||
throw new ApiError(
|
||
ErrorCode.unknownError,
|
||
envelope.message ?? envelope.error ?? "API call failed",
|
||
);
|
||
}
|
||
return envelope.data;
|
||
}
|