From 12f1344138e1836e3dca99b35d6957fb1fe2d874 Mon Sep 17 00:00:00 2001 From: thesn10 <38666407+thesn10@users.noreply.github.com> Date: Fri, 26 Jun 2026 19:13:17 +0200 Subject: [PATCH] better error handling --- app/src/app/listing/[pk]/page.tsx | 4 ++-- app/src/components/ui/Toast.tsx | 22 ++++++++++++---------- app/src/hooks/useTx.ts | 30 ++++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/app/src/app/listing/[pk]/page.tsx b/app/src/app/listing/[pk]/page.tsx index 052d462..114a496 100644 --- a/app/src/app/listing/[pk]/page.tsx +++ b/app/src/app/listing/[pk]/page.tsx @@ -60,8 +60,8 @@ export default function ListingPage({ params }: { params: Promise<{ pk: string } [['listing', pk], ['orders', pk]], 'create_order', ) - } catch (err) { - console.error('create_order failed:', err) + } catch { + // error already shown via toast in useTx } finally { setOrderLoading(false) } diff --git a/app/src/components/ui/Toast.tsx b/app/src/components/ui/Toast.tsx index 2240277..34740fe 100644 --- a/app/src/components/ui/Toast.tsx +++ b/app/src/components/ui/Toast.tsx @@ -2,24 +2,26 @@ import { createContext, useCallback, useContext, useState, type ReactNode } from 'react' -const ToastCtx = createContext<(msg: string) => void>(() => {}) +type ToastFn = (msg: string, type?: 'success' | 'error') => void + +const ToastCtx = createContext(() => {}) export function useToast() { return useContext(ToastCtx) } export function ToastProvider({ children }: { children: ReactNode }) { - const [msg, setMsg] = useState('') + const [state, setState] = useState<{ msg: string; type: 'success' | 'error' } | null>(null) - const show = useCallback((m: string) => { - setMsg(m) - setTimeout(() => setMsg(''), 2800) + const show = useCallback((m, type = 'success') => { + setState({ msg: m, type }) + setTimeout(() => setState(null), type === 'error' ? 4500 : 2800) }, []) return ( {children} - {msg && ( + {state && (
- {msg} + {state.msg}
)}
diff --git a/app/src/hooks/useTx.ts b/app/src/hooks/useTx.ts index 9080460..ce47973 100644 --- a/app/src/hooks/useTx.ts +++ b/app/src/hooks/useTx.ts @@ -39,10 +39,15 @@ export function useTx() { const signed = await signTransactionMessageWithSigners(txMsg) assertIsTransactionWithBlockhashLifetime(signed) - await sendAndConfirmTransactionFactory({ rpc: rpc as never, rpcSubscriptions: rpcSubscriptions as never })( - signed as never, - { commitment: 'confirmed' }, - ) + try { + await sendAndConfirmTransactionFactory({ rpc: rpc as never, rpcSubscriptions: rpcSubscriptions as never })( + signed as never, + { commitment: 'confirmed' }, + ) + } catch (err) { + toast(friendlyTxError(err), 'error') + throw err + } toast(`Tx confirmed — ${label}`) for (const key of invalidateKeys) { @@ -50,3 +55,20 @@ export function useTx() { } } } + +function friendlyTxError(err: unknown): string { + const msg = err instanceof Error ? err.message : String(err) + if ( + msg.includes('Attempt to debit an account but found no record of a prior credit') || + msg.includes('AccountNotFound') + ) { + return 'Insufficient SOL — please fund your wallet and try again.' + } + if (msg.includes('insufficient lamports') || msg.includes('insufficient funds')) { + return 'Insufficient SOL — please fund your wallet and try again.' + } + if (msg.includes('User rejected') || msg.includes('Transaction was not confirmed')) { + return 'Transaction cancelled.' + } + return 'Transaction failed — please try again.' +}