mirror of
https://github.com/YuzuZensai/VRC-Circle.git
synced 2026-09-14 03:10:01 +00:00
✨ feat: Initial commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import type { ApiError, ApiErrorCode, IpcResult } from "../../shared/types/result";
|
||||
|
||||
interface HttpLike {
|
||||
status?: number;
|
||||
statusCode?: number;
|
||||
status_code?: number;
|
||||
response?: { status?: number; headers?: Record<string, string> };
|
||||
headers?: Record<string, string>;
|
||||
message?: string;
|
||||
code?: ApiErrorCode;
|
||||
methods?: ("totp" | "emailOtp")[];
|
||||
error?: { status_code?: number; statusCode?: number; status?: number };
|
||||
}
|
||||
|
||||
function statusOf(e: HttpLike): number | undefined {
|
||||
return (
|
||||
e.status ??
|
||||
e.statusCode ??
|
||||
e.status_code ??
|
||||
e.response?.status ??
|
||||
e.error?.status_code ??
|
||||
e.error?.statusCode ??
|
||||
e.error?.status
|
||||
);
|
||||
}
|
||||
|
||||
export function httpStatusOf(err: unknown): number | undefined {
|
||||
return statusOf((err ?? {}) as HttpLike);
|
||||
}
|
||||
|
||||
function retryAfterOf(e: HttpLike): number | undefined {
|
||||
const raw = e.response?.headers?.["retry-after"] ?? e.headers?.["retry-after"];
|
||||
const n = raw != null ? Number(raw) : NaN;
|
||||
return Number.isFinite(n) ? n : undefined;
|
||||
}
|
||||
|
||||
export function toApiError(err: unknown): ApiError {
|
||||
const e = (err ?? {}) as HttpLike;
|
||||
const status = statusOf(e);
|
||||
const message = e.message ?? "Unexpected error";
|
||||
|
||||
if (e.code) return { code: e.code, message, methods: e.methods };
|
||||
|
||||
let code: ApiErrorCode = "unknown";
|
||||
if (status === 401) code = "unauthorized";
|
||||
else if (status === 404) code = "not_found";
|
||||
else if (status === 429) code = "rate_limited";
|
||||
else if (status === undefined && /network|fetch|ENOTFOUND|ECONN/i.test(message)) code = "network";
|
||||
|
||||
return { code, message, retryAfter: retryAfterOf(e) };
|
||||
}
|
||||
|
||||
export async function guard<T>(fn: () => Promise<T>): Promise<IpcResult<T>> {
|
||||
try {
|
||||
return { ok: true, data: await fn() };
|
||||
} catch (err) {
|
||||
return { ok: false, error: toApiError(err) };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user