UNPKG

@trpc/server

Version:

The tRPC server library

73 lines (67 loc) • 2.53 kB
import * as nextNavigation from 'next/navigation'; import type { TRPCError } from '../../@trpc/server'; import { TRPCRedirectError } from './redirect'; /** * @remarks The helpers from `next/dist/client/components/*` has been removed in Next.js 15. * Inlining them here instead... * @see https://github.com/vercel/next.js/blob/5ae286ffd664e5c76841ed64f6e2da85a0835922/packages/next/src/client/components/redirect.ts#L97-L123 */ const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT'; function isRedirectError(error: unknown) { if ( typeof error !== 'object' || error === null || !('digest' in error) || typeof error.digest !== 'string' ) { return false; } const [errorCode, type, destination, status] = error.digest.split(';', 4); const statusCode = Number(status); return ( errorCode === REDIRECT_ERROR_CODE && (type === 'replace' || type === 'push') && typeof destination === 'string' && !isNaN(statusCode) ); } /** * @remarks The helpers from `next/dist/client/components/*` has been removed in Next.js 15. * Inlining them here instead... * @see https://github.com/vercel/next.js/blob/5ae286ffd664e5c76841ed64f6e2da85a0835922/packages/next/src/client/components/not-found.ts#L33-L39 */ const NOT_FOUND_ERROR_CODE = 'NEXT_NOT_FOUND'; function isNotFoundError(error: unknown) { if (typeof error !== 'object' || error === null || !('digest' in error)) { return false; } return error.digest === NOT_FOUND_ERROR_CODE; } /** * Turns a caught `TRPCError` into the Next.js control-flow error it stands * for: a `NOT_FOUND` code calls `notFound()`, a `TRPCRedirectError` calls * `redirect()`, and a `notFound()` or `redirect()` error in `cause` is * rethrown. It only takes a `TRPCError`; rethrow Next.js's own errors, such * as those `nextAppDirCaller` throws, yourself. */ export const rethrowNextErrors = (error: TRPCError) => { if (error.code === 'NOT_FOUND') { nextNavigation.notFound(); } if (error instanceof TRPCRedirectError) { nextNavigation.redirect(...error.args); } const { cause } = error; // Next.js 15 has `unstable_rethrow`. Use that if it exists. if ( 'unstable_rethrow' in nextNavigation && typeof nextNavigation.unstable_rethrow === 'function' ) { nextNavigation.unstable_rethrow(cause); } // Before Next.js 15, we have to check and rethrow the error manually. if (isRedirectError(cause) || isNotFoundError(cause)) { // oxlint-disable-next-line typescript/no-non-null-assertion throw cause!; } };