next-safe-action
Version:
Type safe and validated Server Actions in your Next.js project.
119 lines (118 loc) • 4.83 kB
JavaScript
//#region src/next/errors/bailout-to-csr.ts
const BAILOUT_TO_CSR = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
/** Checks if a passed argument is an error that is thrown if we want to bail out to client-side rendering. */
function isBailoutToCSRError(err) {
if (typeof err !== "object" || err === null || !("digest" in err)) return false;
return err.digest === BAILOUT_TO_CSR;
}
//#endregion
//#region src/next/errors/http-access-fallback.ts
const ALLOWED_CODES = new Set(Object.values({
NOT_FOUND: 404,
FORBIDDEN: 403,
UNAUTHORIZED: 401
}));
const HTTP_ERROR_FALLBACK_ERROR_CODE = "NEXT_HTTP_ERROR_FALLBACK";
/**
* Checks an error to determine if it's an error generated by
* the HTTP navigation APIs `notFound()`, `forbidden()` or `unauthorized()`.
*
* @param error the error that may reference a HTTP access error
* @returns true if the error is a HTTP access error
*/
function isHTTPAccessFallbackError(error) {
if (typeof error !== "object" || error === null || !("digest" in error) || typeof error.digest !== "string") return false;
const [prefix, httpStatus] = error.digest.split(";");
return prefix === HTTP_ERROR_FALLBACK_ERROR_CODE && ALLOWED_CODES.has(Number(httpStatus));
}
function getAccessFallbackHTTPStatus(error) {
const httpStatus = error.digest.split(";")[1];
return Number(httpStatus);
}
//#endregion
//#region src/next/errors/redirect.ts
var RedirectStatusCode = /* @__PURE__ */ function(RedirectStatusCode) {
RedirectStatusCode[RedirectStatusCode["SeeOther"] = 303] = "SeeOther";
RedirectStatusCode[RedirectStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
RedirectStatusCode[RedirectStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
return RedirectStatusCode;
}(RedirectStatusCode || {});
const REDIRECT_ERROR_CODE = "NEXT_REDIRECT";
/**
* Checks an error to determine if it's an error generated by the
* `redirect(url)` helper.
*
* @param error the error that may reference a redirect error
* @returns true if the error is a redirect error
*/
function isRedirectError(error) {
if (typeof error !== "object" || error === null || !("digest" in error) || typeof error.digest !== "string") return false;
const digest = error.digest.split(";");
const [errorCode, type] = digest;
const destination = digest.slice(2, -2).join(";");
const status = digest.at(-2);
const statusCode = Number(status);
return errorCode === REDIRECT_ERROR_CODE && (type === "replace" || type === "push") && typeof destination === "string" && !isNaN(statusCode) && statusCode in RedirectStatusCode;
}
//#endregion
//#region src/next/errors/router.ts
/**
* Returns true if the error is a navigation signal error. These errors are
* thrown by user code to perform navigation operations and interrupt the React
* render.
*/
function isNextRouterError(error) {
return isRedirectError(error) || isHTTPAccessFallbackError(error);
}
//#endregion
//#region src/next/errors/dynamic-usage.ts
const DYNAMIC_ERROR_CODE = "DYNAMIC_SERVER_USAGE";
function isDynamicServerError(err) {
if (typeof err !== "object" || err === null || !("digest" in err) || typeof err.digest !== "string") return false;
return err.digest === DYNAMIC_ERROR_CODE;
}
function isDynamicPostponeReason(reason) {
return reason.includes("needs to bail out of prerendering at this point because it used") && reason.includes("Learn more: https://nextjs.org/docs/messages/ppr-caught-error");
}
function isDynamicPostpone(err) {
if (typeof err === "object" && err !== null && typeof err.message === "string") return isDynamicPostponeReason(err.message);
return false;
}
const isDynamicUsageError = (err) => isDynamicServerError(err) || isBailoutToCSRError(err) || isNextRouterError(err) || isDynamicPostpone(err);
//#endregion
//#region src/next/errors/postpone.ts
const REACT_POSTPONE_TYPE = Symbol.for("react.postpone");
function isPostpone(error) {
return typeof error === "object" && error !== null && error.$$typeof === REACT_POSTPONE_TYPE;
}
//#endregion
//#region src/next/errors/index.ts
var FrameworkErrorHandler = class FrameworkErrorHandler {
#frameworkError;
static isNavigationError(error) {
return isNextRouterError(error) || isBailoutToCSRError(error) || isDynamicUsageError(error) || isPostpone(error);
}
static getNavigationKind(error) {
if (isRedirectError(error)) return "redirect";
if (isHTTPAccessFallbackError(error)) {
const status = getAccessFallbackHTTPStatus(error);
if (status === 404) return "notFound";
if (status === 403) return "forbidden";
if (status === 401) return "unauthorized";
}
return "other";
}
handleError(e) {
if (FrameworkErrorHandler.isNavigationError(e)) {
this.#frameworkError = e;
return;
}
throw e;
}
get error() {
return this.#frameworkError;
}
};
//#endregion
export { FrameworkErrorHandler as t };
//# sourceMappingURL=errors-DSpBUWAx.mjs.map