Files
zerobyte/app/server/utils/errors.ts

62 lines
2.2 KiB
TypeScript

import { HttpError } from "http-errors-enhanced";
import { sanitizeSensitiveData } from "@zerobyte/core/node";
import { isResticError } from "@zerobyte/core/restic";
import { toErrorDetails as getErrorDetails, toMessage as getMessage } from "@zerobyte/core/utils";
import { Cause, Effect, Exit, Option } from "effect";
const formatAllowedHostsMessage = (message: string) => {
const referencesAllowedHosts = /\ballowed\s+hosts?\b|\ballowedHosts\b/i.test(message);
const referencesBaseUrlResolution = /\bbase\s*url\b|\bhost\b|\bfallback\s+URL\b/i.test(message);
if (!referencesAllowedHosts || !referencesBaseUrlResolution) {
return message;
}
const requestedHost = message.match(/\bHost\s+"([^"]+)"/i)?.[1];
const configuredHosts = message.match(/\bAllowed\s+hosts:\s*(.*?)(?:\.\s+Add\b|$)/i)?.[1]?.trim();
const hostDetails = [
requestedHost ? `Requested host: ${requestedHost}.` : undefined,
configuredHosts ? `Configured BASE_URL/TRUSTED_ORIGINS hosts: ${configuredHosts}.` : undefined,
].filter(Boolean);
return [
"Could not resolve the auth base URL from this request.",
...hostDetails,
"Set BASE_URL to the URL you use to access Zerobyte, or add this origin to TRUSTED_ORIGINS.",
].join(" ");
};
export const handleServiceError = (error: unknown) => {
if (error instanceof HttpError) {
return { message: sanitizeSensitiveData(error.message), status: error.statusCode };
}
if (isResticError(error)) {
return {
message: sanitizeSensitiveData(error.summary),
details: error.details ? sanitizeSensitiveData(error.details) : undefined,
status: 500 as const,
};
}
return { message: formatAllowedHostsMessage(sanitizeSensitiveData(toMessage(error))), status: 500 as const };
};
export const toMessage = (err: unknown): string => {
return sanitizeSensitiveData(getMessage(err));
};
export const toErrorDetails = (err: unknown): string => {
return sanitizeSensitiveData(getErrorDetails(err));
};
export const runEffectPromise = <A, E>(effect: Effect.Effect<A, E, never>) => {
return Effect.runPromiseExit(effect).then((exit) => {
if (Exit.isSuccess(exit)) {
return exit.value;
}
throw Option.getOrUndefined(Cause.failureOption(exit.cause)) ?? Cause.squash(exit.cause);
});
};