This guide shows you how to handle a failed wallet request, so a user who cancels isn’t shown an error and a real failure isn’t hidden.
- Wrap the wallet call in
try/catch. - Check the error with
isWalletError()and a code fromWalletErrorCode. - Treat
WalletErrorCode.UserRejectedas a cancel: leave your UI as it was. - Show anything else to the user, with a way to retry.
"use client"
import { useState } from "react"
import { isWalletError, useAccount, WalletErrorCode } from "@dogeos/dogeos-sdk"
export function SignButton({ message }: { message: string }) {
const { address, signMessage } = useAccount()
const [error, setError] = useState<string | null>(null)
async function onSign() {
if (!address || !signMessage) return
setError(null)
try {
await signMessage({ message })
} catch (err) {
if (isWalletError(err, WalletErrorCode.UserRejected)) return
setError(err instanceof Error ? err.message : "Signing failed. Try again.")
}
}
return (
<div>
<button onClick={onSign}>Sign</button>
{error ? <p role="alert">{error}</p> : null}
</div>
)
}The same check works for connect, switchChain, signing and direct provider requests. If you use useWalletHost().connect() in a browser, closing the modal without connecting also rejects with UserRejected.
Inside MyDoge, cancelling a network switch rejects with code -1 instead of 4001. If you switch networks inside MyDoge, treat that as a cancel too: isWalletError(error) && error.code === -1.
If you add a network the wallet may not know, also check WalletErrorCode.UnsupportedChain (4902). The Errors reference lists every code.