Error handling
Typed error codes, stable messages, and how the SDK signals failures.
Every failure the SDK raises is a BridgeError with a stable code on the ErrorCode map. Branch on the code, not on the message text.
The shape
import { BridgeError, ErrorCode, ErrorMessage } from "@zethub/bridge";
try {
const tx = await sdk.bridge.rawTxBuilder.send({ ... });
} catch (err) {
if (err instanceof BridgeError) {
console.log(err.code); // a value from ErrorCode
console.log(err.message); // human readable copy from ErrorMessage
console.log(err.cause); // underlying error, when there was one
}
}When errors are thrown
The SDK returns unsigned transactions. It does not run flows, so it does not surface flow errors. Every method that touches the network can throw a BridgeError if:
- the requested route is invalid or misconfigured,
- the network returns a bad response,
- the input fails validation (bad amount, bad address, etc).
Signing and broadcasting errors come from your wallet library, not the SDK. Use BridgeError.from(err) to normalise them.
Common codes
| Code | When it happens |
|---|---|
MISSING_SOURCE | The passed NetworkId is not registered in the current environment. |
MISSING_EVM_CHAIN_ID | The EVM network in the config is missing its chain id. Should not happen with the built in networks. |
MISSING_FORWARDER | A Stellar destination is missing its CctpForwarder address in the network config. |
MISSING_TRUSTLINE | The Stellar recipient has no trustline for the asset. |
UNSUPPORTED_ASSET | The requested asset is not on the given network. |
UNSUPPORTED_ROUTE | Neither chain family has a connector registered. |
MISMATCHED_ENVIRONMENTS | The source and destination tokens live on different environments. |
SAME_NETWORK | The source and destination are the same network. |
ATTESTATION_TIMEOUT | Iris did not attest before the timeout. Fetch again later. |
RPC_ERROR | Every configured RPC endpoint failed. |
RPC_TIMEOUT | An RPC call timed out. |
WALLET_SIGN_REJECTED | Normalised from a wallet library's user rejected error. |
WRONG_NETWORK | Normalised from a wallet library's wrong chain error. |
AMOUNT_EXCEEDS_BALANCE | Normalised from a wallet library's insufficient funds error. |
Classify a wallet error
BridgeError.from(err, fallback?) sniffs a unknown value and returns a BridgeError with the best matching code. If nothing matches, it returns one with the fallback (default UNKNOWN).
try {
await wallet.sendTransaction({ ... });
} catch (err) {
const known = BridgeError.from(err);
if (known.code === "WALLET_SIGN_REJECTED") {
// user cancelled, do not retry
return;
}
throw known;
}The classifier catches common phrasings:
user rejected,user denied,action_rejected→WALLET_SIGN_REJECTEDinsufficient funds→AMOUNT_EXCEEDS_BALANCEwrong network,chain mismatch→WRONG_NETWORK
Messages are constants
Every message lives in an exported map keyed by code, so you can translate or replace them.
import { ErrorMessage } from "@zethub/bridge";
ErrorMessage.MISSING_TRUSTLINE;
// "The Stellar recipient has no trustline for this asset. Establish the trustline before bridging."Override in bulk when localising:
const spanish: typeof ErrorMessage = {
...ErrorMessage,
MISSING_TRUSTLINE: "El destinatario no tiene línea de confianza para USDC.",
// ...
};See the full error code reference for every code and its default message.