Szymon
Szymon2w ago

error handling

Hi, what is best method to handle errors like incorrect email or password etc, cuz when im using throw new trpcerror i have error info in left down corner
7 Replies
FluX
FluX2w ago
I guess what you're referring to is the little error popup in Next.js. What I like to do is to wrap my mutation call in a try/catch wrapper function and show a toast in case of errors. Not sure if this is the best solution but it works.
import { toast } from "sonner"

type TryFnHandler = () => any | Promise<any>

interface TryFnOptions<T extends TryFnHandler> {
onSuccess?: (result: Awaited<ReturnType<T>>) => void
onError?: (error: unknown) => void
successMessage?: string | ((result: Awaited<ReturnType<T>>) => string)
errorMessage?: string
}

export async function tryTo<T extends TryFnHandler>(
handler: T,
opts: TryFnOptions<T> = {},
) {
try {
const result = await handler()

if (opts.onSuccess) {
opts.onSuccess(result)
}

if (opts.successMessage) {
if (typeof opts.successMessage === "function") {
toast.success(opts.successMessage(result))
} else {
toast.success(opts.successMessage)
}
}
} catch (error) {
if (opts.onError) {
opts.onError(error)
}

if (opts.errorMessage) {
toast.error(opts.errorMessage)
} else {
const message =
error instanceof Error
? error.message
: "Oh no, something went wrong!"
toast.error(message)
}
}
}
import { toast } from "sonner"

type TryFnHandler = () => any | Promise<any>

interface TryFnOptions<T extends TryFnHandler> {
onSuccess?: (result: Awaited<ReturnType<T>>) => void
onError?: (error: unknown) => void
successMessage?: string | ((result: Awaited<ReturnType<T>>) => string)
errorMessage?: string
}

export async function tryTo<T extends TryFnHandler>(
handler: T,
opts: TryFnOptions<T> = {},
) {
try {
const result = await handler()

if (opts.onSuccess) {
opts.onSuccess(result)
}

if (opts.successMessage) {
if (typeof opts.successMessage === "function") {
toast.success(opts.successMessage(result))
} else {
toast.success(opts.successMessage)
}
}
} catch (error) {
if (opts.onError) {
opts.onError(error)
}

if (opts.errorMessage) {
toast.error(opts.errorMessage)
} else {
const message =
error instanceof Error
? error.message
: "Oh no, something went wrong!"
toast.error(message)
}
}
}
const mutation = trpc.yourHandler.useMutation()

async function doMutation {
await tryTo(async () => {
await mutation.mutateAsync()
})
}
const mutation = trpc.yourHandler.useMutation()

async function doMutation {
await tryTo(async () => {
await mutation.mutateAsync()
})
}
Szymon
SzymonOP2w ago
thx man ❤️
codecret | Software Engineer
actually this returned the whole bunch of objects whereas i wanna see the message
codecret | Software Engineer
this is type object trpcclienterror
No description
FluX
FluX6d ago
If you went with this approach and used the tryTo function, I think you could check in the catch block if it's a TRPCClientError and return the message.
if (error instanceof TRPCClientError) {
const message = // get message from error
}
if (error instanceof TRPCClientError) {
const message = // get message from error
}
Haven't tried it tho
codecret | Software Engineer
that's true, I wonder if there is another way to handle zod validations, i think it can be handled from the front end anyways ?

Did you find this page helpful?