fetchStatus: check the fetch error
All checks were successful
/ depoly (push) Successful in 1m21s

This commit is contained in:
thislight 2025-01-01 21:08:26 +08:00
parent d7e1358495
commit 66b593add8
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E
2 changed files with 76 additions and 15 deletions

View file

@ -1,6 +1,7 @@
import { createCacheBucket } from "~platform/cache";
import { MastoHttpError, MastoTimeoutError, MastoUnexpectedError } from "masto";
export const CACHE_BUCKET_NAME = "mastodon"
export const CACHE_BUCKET_NAME = "mastodon";
export const cacheBucket = /* @__PURE__ */ createCacheBucket(CACHE_BUCKET_NAME);
@ -8,12 +9,12 @@ export function toSmallCamelCase<T>(object: T) :T {
if (!object || typeof object !== "object") {
return object;
} else if (Array.isArray(object)) {
return object.map(toSmallCamelCase) as T
return object.map(toSmallCamelCase) as T;
}
const result = {} as Record<keyof any, unknown>;
for (const k in object) {
const value = toSmallCamelCase(object[k])
const value = toSmallCamelCase(object[k]);
const nk =
typeof k === "string"
? k.replace(/_(.)/g, (_, match) => match.toUpperCase())
@ -23,3 +24,61 @@ export function toSmallCamelCase<T>(object: T) :T {
return result as T;
}
function contentTypeOf(headers: Headers) {
const raw = headers.get("Content-Type")?.replace(/\s*;.*$/, "");
if (!raw) {
return;
}
return raw;
}
/**
* Wrpas the error reason into masto's errors:
* {@link MastoHttpError} if the reason is a {@link Response},
* {@link MastoTimeoutError} if the reason is a timeout error.
*
* @throws If the reason is unexpected, {@link MastoUnexpectedError} will be thrown.
*/
export async function wrapsError(reason: Response): Promise<MastoHttpError>;
export async function wrapsError(reason: {
name: "TimeoutError";
}): Promise<MastoTimeoutError>;
export async function wrapsError<T>(reason: T): Promise<T>;
export async function wrapsError(reason: unknown) {
if (reason instanceof Response) {
const contentType = contentTypeOf(reason.headers);
if (!contentType) {
throw new MastoUnexpectedError(
"The server returned data with an unknown encoding. The server may be down",
);
}
const data = await reason.json();
const {
error: message,
errorDescription,
details,
...additionalProperties
} = data;
return new MastoHttpError(
{
statusCode: reason.status,
message,
description: errorDescription,
details,
additionalProperties,
},
{ cause: reason },
);
}
if (reason && (reason as { name?: string }).name === "TimeoutError") {
return new MastoTimeoutError("Request timed out", { cause: reason });
}
return reason;
}

View file

@ -1,12 +1,7 @@
import { CachedFetch } from "~platform/cache";
import { cacheBucket, toSmallCamelCase } from "./base";
import {
isAccountKey,
type RemoteServer,
} from "../accounts/stores";
import type { mastodon } from "masto";
import { cacheBucket, toSmallCamelCase, wrapsError } from "./base";
import { isAccountKey, type RemoteServer } from "../accounts/stores";
import { type mastodon } from "masto";
export const fetchStatus = /* @__PURE__ */ new CachedFetch(
cacheBucket,
@ -23,8 +18,15 @@ export const fetchStatus = /* @__PURE__ */ new CachedFetch(
};
},
async (response) => {
try {
if (!response.ok) {
throw response;
}
return toSmallCamelCase(
await response.json(),
) as unknown as mastodon.v1.Status;
} catch (reason) {
throw wrapsError(reason);
}
},
);