48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
import { HTTPError } from "ky";
|
|
|
|
export interface ApiErrorBody {
|
|
message?: string;
|
|
errors?: Record<string, string[]>;
|
|
}
|
|
|
|
/** 讀取 ky 已解析的 API 錯誤,不重複消耗 response body。 */
|
|
export function getApiErrorBody(error: unknown): ApiErrorBody | null {
|
|
if (
|
|
error instanceof HTTPError &&
|
|
error.data &&
|
|
typeof error.data === "object"
|
|
) {
|
|
return error.data as ApiErrorBody;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function getApiErrorStatus(error: unknown): number | null {
|
|
return error instanceof HTTPError ? error.response.status : null;
|
|
}
|
|
|
|
export function getApiErrorMessage(
|
|
error: unknown,
|
|
fallback = "操作失敗,請稍後再試。",
|
|
): string {
|
|
const body = getApiErrorBody(error);
|
|
if (body?.message) {
|
|
return body.message;
|
|
}
|
|
|
|
const firstFieldError = Object.values(body?.errors ?? {})[0]?.[0];
|
|
if (firstFieldError) {
|
|
return firstFieldError;
|
|
}
|
|
|
|
return error instanceof Error ? error.message : fallback;
|
|
}
|
|
|
|
export function isUnregisteredPhoneError(error: unknown): boolean {
|
|
return (
|
|
getApiErrorStatus(error) === 401 &&
|
|
getApiErrorBody(error)?.message === "手機門號不存在或尚未註冊"
|
|
);
|
|
}
|