Files
fullstack-starter/apps/server/src/routes/api/rpc.$.ts

62 lines
1.6 KiB
TypeScript

import { ORPCError, onError, ValidationError } from '@orpc/server'
import { RPCHandler } from '@orpc/server/fetch'
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'
import { router } from '@/server/api/routers'
const handler = new RPCHandler(router, {
interceptors: [
onError((error) => {
console.error(error)
}),
],
clientInterceptors: [
onError((error) => {
if (
error instanceof ORPCError &&
error.code === 'BAD_REQUEST' &&
error.cause instanceof ValidationError
) {
// If you only use Zod you can safely cast to ZodIssue[]
const zodError = new z.ZodError(
error.cause.issues as z.core.$ZodIssue[],
)
throw new ORPCError('INPUT_VALIDATION_FAILED', {
status: 422,
message: z.prettifyError(zodError),
data: z.flattenError(zodError),
cause: error.cause,
})
}
if (
error instanceof ORPCError &&
error.code === 'INTERNAL_SERVER_ERROR' &&
error.cause instanceof ValidationError
) {
throw new ORPCError('OUTPUT_VALIDATION_FAILED', {
cause: error.cause,
})
}
}),
],
})
export const Route = createFileRoute('/api/rpc/$')({
server: {
handlers: {
ANY: async ({ request }) => {
const { response } = await handler.handle(request, {
prefix: '/api/rpc',
context: {
headers: request.headers,
},
})
return response ?? new Response('Not Found', { status: 404 })
},
},
},
})