Logging trpc errors in production

What is the proper place for logging errors in production originating from trpc when I use NEXT 14 app router trpc setup. Should I log from nextjs trpc api route handler?
const createContext = async (req: NextRequest) => {
return createTRPCContext({
headers: req.headers,
});
};

const handler = (req: NextRequest) =>
fetchRequestHandler({
endpoint: '/api/trpc',
req,
router: appRouter,
createContext: () => createContext(req),
onError: ({ path, error }) => {
if (serverEnv.NODE_ENV === 'development') {
trpcLogger.error(
`❌ tRPC failed on ${path ?? '<no-path>'}: ${error.message}`,
);
}
},
});

export { handler as GET, handler as POST };
const createContext = async (req: NextRequest) => {
return createTRPCContext({
headers: req.headers,
});
};

const handler = (req: NextRequest) =>
fetchRequestHandler({
endpoint: '/api/trpc',
req,
router: appRouter,
createContext: () => createContext(req),
onError: ({ path, error }) => {
if (serverEnv.NODE_ENV === 'development') {
trpcLogger.error(
`❌ tRPC failed on ${path ?? '<no-path>'}: ${error.message}`,
);
}
},
});

export { handler as GET, handler as POST };
Or maybe from server trpcproxyclient handler??
export const api = createTRPCProxyClient<AppRouter>({
transformer,
links: [
loggerLink({
enabled: (op) =>
process.env.NODE_ENV === 'development' ||
(op.direction === 'down' && op.result instanceof Error),
}),
/**
* Custom RSC link that lets us invoke procedures without using http requests. Since Server
* Components always run on the server, we can just call the procedure as a function.
*/
() =>
({ op }) =>
observable((observer) => {
createContext()
.then((ctx) => {
return callProcedure({
procedures: appRouter._def.procedures,
path: op.path,
rawInput: op.input,
ctx,
type: op.type,
});
})
.then((data) => {
observer.next({ result: { data } });
observer.complete();
})
.catch((cause: TRPCErrorResponse) => {
observer.error(TRPCClientError.from(cause));
});
}),
],
});
export const api = createTRPCProxyClient<AppRouter>({
transformer,
links: [
loggerLink({
enabled: (op) =>
process.env.NODE_ENV === 'development' ||
(op.direction === 'down' && op.result instanceof Error),
}),
/**
* Custom RSC link that lets us invoke procedures without using http requests. Since Server
* Components always run on the server, we can just call the procedure as a function.
*/
() =>
({ op }) =>
observable((observer) => {
createContext()
.then((ctx) => {
return callProcedure({
procedures: appRouter._def.procedures,
path: op.path,
rawInput: op.input,
ctx,
type: op.type,
});
})
.then((data) => {
observer.next({ result: { data } });
observer.complete();
})
.catch((cause: TRPCErrorResponse) => {
observer.error(TRPCClientError.from(cause));
});
}),
],
});
In the loggerlink? or catch of the observable?? Im but confused where errors originate from
2 Replies
Mugetsu
Mugetsu6mo ago
P.S. Im using custom PINO logger and not deploying to vercel
Mozart's_Ghost
Mozart's_Ghost6mo ago
bump