TRPC Handle TRPCError

715 views Asked by At

I am making an app with next js and trpc, when I make a query with trpc and trhow an error occurs, the client side does not receive the error.

My Page:

"use client"

import { useRouter, useSearchParams } from "next/navigation";
import { trpc } from "../_trpc/client";
import { Loader2 } from "lucide-react";
    
const Page = () => {

    const router = useRouter()
    const searchParams = useSearchParams()
    const origin = searchParams.get("origin")

    const { data: user, isLoading, isSuccess, error } = trpc.authCallback.useQuery(undefined, {
        retry: true,
        retryDelay: 500
    })

    console.log(error) // always returns null

    return (
        <div className="w-full mt-24 flex justify-center">
            <div className="flex flex-col items-center gap-2">
                <Loader2 className="h-8 w-8 animate-spin text-zinc-800" />
                <h3 className="font-semibold text-xl">
                    Setting up your account...
                </h3>
                <p>
                    You will be redirected automaticly
                </p>
            </div>
        </div>
    );
}

export default Page;

TRPC code:

    import { createDbUser, getDbUser, getKindeUser } from '@/services/auth';
    import { publicProcedure, router } from './trpc';
    import { TRPCError } from '@trpc/server'
    import { getKindeServerSession } from '@kinde-oss/kinde-auth-nextjs/server';
    import { db } from '@/db';
    
    export
      const appRouter = router({
        // query to get data
        // mutation to modify data
    
        authCallback: publicProcedure.query(async () => {
/// ...
            throw new TRPCError({ code: 'UNAUTHORIZED' }) // throw this error to handle it on my page.tsx

/// ...
          return { success: true }
        })
      });
    
    // Export type router type signature,
    // NOT the router itself.
    export type AppRouter = typeof appRouter;

Does anyone know why I'm not getting the error on my client side? I already tried onError, but it seems that this function was removed on the new trpc update.

when I call this "http://localhost:3000/api/trpc/call-back" on my browser, I do see the error. So the error is being sent but it doesn't get to the client side??

4

There are 4 answers

0
kralj.sam On

If what I think is correct, you and I are practicing with the same project, and I had the same problem.

If you've got a HTTP-405 then change what you'll have to change what you're exporting const handler as ->

    import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
    import { appRouter } from '@/trpc';
    import { NextRequest } from "next/server";
    
    const handler = (req: NextRequest) => fetchRequestHandler({
        endpoint: '/api/trpc',
        req,
        router: appRouter,
        createContext: () => ({}),
    });
    
    export { handler as GET, handler as POST }
 
0
kralj.sam On
  1. Also consider adding these lines to your .gitignore file
    .env*.local
    .env
    .env.local
    .env.staging

This is because making your PrismaDB credentials invalidates them immediately, if you've noticed, you always get an email from PlanetscaleDB saying it's been invalidated, so if that's the case;

  1. Create new credentials for your PrismaDB and push changes to the database
    npx prisma db push
  1. Sign in to your server on localhost before going to the /auth-callback route because at that moment there's no existing user to work with.
0
Aman Sharma On

along with the onSuccess change,

which is this -

   const { data, error } = trpc.authCallback.useQuery(undefined);

      useEffect(() => {
        if (data?.success) {
          router.push(origin ? `/${origin}` : "/dashboard");
        } else if (error?.data?.code === "UNAUTHORIZED") {
          console.log('error: ', error);
          router.push("/sign-in");
        }
      }, [data, error, router, origin]);

and adding await before every getUser worked for me.

0
Rohit Sinha On

you can modify the useQuery option retry like below to access the error object:

const { data, isSuccess } = trpc.authCallback.useQuery(undefined, {
        retry: (failureCount, error) => {
            if (failureCount > threshold) {
                //Do Something or Nothing
            }
            if (error.data?.code === errorCode) {
                // operations to perform on this errorCode
            }
            // return false at any point to exit out of retry loop
            return true;
        },
        retryDelay: 500,
    })