UNPKG

next-safe-action

Version:

Type safe and validated Server Actions in your Next.js project.

119 lines (118 loc) 4.83 kB
//#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