Handling errors
When a BreezSdk method fails, it returns an SdkError (SdkException in Kotlin and C#). Each kind of failure is its own variant, so you can match the ones your app handles and fall back to the error's message for the rest. Some variants carry fields with the detail you need to recover, such as the fee a deposit claim requires. Some variants also carry a docs_urldocs_urldocsUrldocsUrldocsUrldocsUrldocsUrlDocsUrlDocsUrl field linking to their section below.
Catching errors
match sdk.prepare_send_payment(request).await {
Ok(prepare_response) => {
info!("Payment prepared: {:?}", prepare_response.payment_method);
}
Err(SdkError::InsufficientFunds { .. }) => {
info!("Not enough funds for this payment");
}
Err(SdkError::CrossChainDisabled { docs_url }) => {
info!("Cross-chain payments are not enabled, see {docs_url}");
}
Err(error) => {
info!("Failed to prepare the payment: {error}");
}
}
do {
let prepareResponse = try await sdk.prepareSendPayment(request: request)
print("Payment prepared: \(prepareResponse.paymentMethod)")
} catch SdkError.InsufficientFunds {
print("Not enough funds for this payment")
} catch SdkError.CrossChainDisabled(let docsUrl) {
print("Cross-chain payments are not enabled, see \(docsUrl)")
} catch {
print("Failed to prepare the payment: \(error)")
}
try {
val prepareResponse = sdk.prepareSendPayment(request)
// Log.v("Breez", "Payment prepared: ${prepareResponse.paymentMethod}")
} catch (e: SdkException.InsufficientFunds) {
// Log.v("Breez", "Not enough funds for this payment")
} catch (e: SdkException.CrossChainDisabled) {
// Log.v("Breez", "Cross-chain payments are not enabled, see ${e.docsUrl}")
} catch (e: SdkException) {
// Log.v("Breez", "Failed to prepare the payment: ${e.message}")
}
try
{
var prepareResponse = await sdk.PrepareSendPayment(request: request);
Console.WriteLine($"Payment prepared: {prepareResponse.paymentMethod}");
}
catch (SdkException.InsufficientFunds)
{
Console.WriteLine("Not enough funds for this payment");
}
catch (SdkException.CrossChainDisabled e)
{
Console.WriteLine($"Cross-chain payments are not enabled, see {e.docsUrl}");
}
catch (SdkException e)
{
Console.WriteLine($"Failed to prepare the payment: {e.Message}");
}
try {
const prepareResponse = await sdk.prepareSendPayment(request)
console.log(`Payment prepared: ${prepareResponse.paymentMethod.type}`)
} catch (error) {
// The SDK throws Error objects. Some also carry a docsUrl linking to the guide.
const sdkError = error as SdkError
console.log(`Failed to prepare the payment: ${sdkError.message}`)
if (sdkError.docsUrl !== undefined) {
console.log(`Learn more: ${sdkError.docsUrl}`)
}
}
try {
const prepareResponse = await sdk.prepareSendPayment(request)
console.log(`Payment prepared: ${prepareResponse.paymentMethod.tag}`)
} catch (error) {
if (SdkError.InsufficientFunds.instanceOf(error)) {
console.log('Not enough funds for this payment')
} else if (SdkError.CrossChainDisabled.instanceOf(error)) {
console.log(`Cross-chain payments are not enabled, see ${error.inner.docsUrl}`)
} else {
console.log(`Failed to prepare the payment: ${String(error)}`)
}
}
try {
final prepareResponse = await sdk.prepareSendPayment(request: request);
print('Payment prepared: ${prepareResponse.paymentMethod}');
} on SdkError_InsufficientFunds {
print('Not enough funds for this payment');
} on SdkError_CrossChainDisabled catch (e) {
print('Cross-chain payments are not enabled, see ${e.docsUrl}');
} catch (e) {
print('Failed to prepare the payment: $e');
}
try:
prepare_response = await sdk.prepare_send_payment(request=request)
except SdkError.InsufficientFunds:
logging.debug("Not enough funds for this payment")
except SdkError.CrossChainDisabled as error:
logging.debug(f"Cross-chain payments are not enabled, see {error.docs_url}")
except Exception as error:
logging.error(f"Failed to prepare the payment: {error}")
raise
else:
logging.debug(f"Payment prepared: {prepare_response.payment_method}")
prepareResponse, err := sdk.PrepareSendPayment(request)
var insufficient *breez_sdk_spark.SdkErrorInsufficientFunds
var disabled *breez_sdk_spark.SdkErrorCrossChainDisabled
switch {
case err == nil:
log.Printf("Payment prepared: %v", prepareResponse.PaymentMethod)
case errors.As(err, &insufficient):
log.Printf("Not enough funds for this payment")
case errors.As(err, &disabled):
log.Printf("Cross-chain payments are not enabled, see %v", disabled.DocsUrl)
default:
log.Printf("Failed to prepare the payment: %v", err)
}
How errors appear differs by language:
- JavaScript (WASM): errors are thrown as standard
Errorobjects, typed asSdkError. The message describes the error, and errors that link to the guide also have adocsUrlproperty. There are no per-variant error types to match on. - React Native: each variant is a class under
SdkError. Match it withinstanceOfand read its fields frominner. - Other languages: each variant is its own error type or case, with its fields available directly.
Deposits the SDK claims in the background don't throw. When one of those claims fails, the reason is recorded on the deposit's claim_errorclaim_errorclaimErrorclaimErrorclaimErrorclaimErrorclaimErrorClaimErrorClaimError instead. It uses the same MaxDepositClaimFeeExceeded, MissingUtxo and DepositTooSmall cases described below, and any other failure is recorded as a generic message. See Handling the outcome.
Error reference
SparkError
An operation on the Spark network failed, such as a transfer or a call to the Spark operators. The message carries the underlying cause.
InsufficientFunds
The balance can't cover the payment and its fees. token_identifiertoken_identifiertokenIdentifiertokenIdentifiertokenIdentifiertokenIdentifiertokenIdentifierTokenIdentifierTokenIdentifier is set when there are insufficient funds to make a token payment. You can check balances with get_infoget_infogetInfogetInfogetInfogetInfogetInfoGetInfoGetInfo.
InvalidUuid
An identifier passed to the SDK is not a valid UUID.
InvalidInput
The request was rejected as invalid: a malformed address or invoice, a missing or out-of-range value, an option that doesn't apply to the request, or a lookup for something that doesn't exist. The message names the problem. Fix the request rather than retrying it unchanged.
CrossChainAmountOutOfRange
The USDC/USDT provider rejected the amount for the route. too_smalltoo_smalltooSmalltooSmalltooSmalltooSmalltooSmallTooSmallTooSmall tells you whether it fell below the minimum or above the maximum, and the published bound is included when the provider publishes one. See Amount limits.
CrossChainRouteUnavailable
The USDC/USDT provider won't serve the route. When temporarytemporarytemporarytemporarytemporarytemporarytemporaryTemporaryTemporary is set, the provider expects the route back shortly and the same request may succeed later. Otherwise pick another route. See Amount limits.
CrossChainDisabled
USDC/USDT payments are not enabled on this SDK instance, so every cross-chain call fails, including get_cross_chain_routesget_cross_chain_routesgetCrossChainRoutesgetCrossChainRoutesgetCrossChainRoutesgetCrossChainRoutesgetCrossChainRoutesGetCrossChainRoutesGetCrossChainRoutes. Enable them by setting cross_chain_configcross_chain_configcrossChainConfigcrossChainConfigcrossChainConfigcrossChainConfigcrossChainConfigCrossChainConfigCrossChainConfig, as described in USDC/USDT configuration.
NetworkError
A request to a remote service failed, for example an LNURL server, the Lightning address service, a fiat rate provider or a USDC/USDT provider. The message carries the service's response.
StorageError
Reading or writing the SDK's local storage failed.
ChainServiceError
The Bitcoin chain service failed, for example while fetching a deposit transaction or the recommended fees. Calls that read the chain, such as claim_depositclaim_depositclaimDepositclaimDepositclaimDepositclaimDepositclaimDepositClaimDepositClaimDeposit, refund_depositrefund_depositrefundDepositrefundDepositrefundDepositrefundDepositrefundDepositRefundDepositRefundDeposit, recommended_feesrecommended_feesrecommendedFeesrecommendedFeesrecommendedFeesrecommendedFeesrecommendedFeesRecommendedFeesRecommendedFees and unilateral exits, can return it.
MaxDepositClaimFeeExceeded
Claiming a deposit costs more than the maximum fee allows, or no maximum fee is set. required_fee_satsrequired_fee_satsrequiredFeeSatsrequiredFeeSatsrequiredFeeSatsrequiredFeeSatsrequiredFeeSatsRequiredFeeSatsRequiredFeeSats gives the fee the claim needs, so you can ask the user to approve it and claim again with a higher maximum. See Handling the outcome.
MissingUtxo
The deposit transaction has no output at the given index, so the transaction id or output index doesn't match a real deposit.
DepositTooSmall
After the claim fee, the deposit would credit less than the dust limit. No maximum fee makes it claimable, but a drop in on-chain fees can. See Handling the outcome.
DepositClaimInProgress
Another claim on this deposit is already running, or an early claim was already made. It is not a failure to show the user, and it needs nothing from you. See Claiming a deposit manually.
RefundReplacementFeeTooLow
A refund for this deposit is already on the network, and the new one doesn't pay enough to replace it. Retry with a fee of at least required_fee_satsrequired_fee_satsrequiredFeeSatsrequiredFeeSatsrequiredFeeSatsrequiredFeeSatsrequiredFeeSatsRequiredFeeSatsRequiredFeeSats. See Tracking a refund.
LnurlError
The LNURL service returned an error while paying or withdrawing. The message carries the service's reason. See LNURL-Pay and LNURL-Withdraw.
Signer
The signer failed, for example while signing or deriving a key. With an external signer, the message carries the error your signer returned. See Using an External Signer.
OptimizationAlreadyRunning
optimize_leavesoptimize_leavesoptimizeLeavesoptimizeLeavesoptimizeLeavesoptimizeLeavesoptimizeLeavesOptimizeLeavesOptimizeLeaves was called while another optimization, automatic or manual, was still running. See Controlling optimization timing.
OptimizationCancelled
The SDK stopped the optimization to free funds for a higher-priority operation, usually a payment. It is not a fault. See Controlling optimization timing.
InsufficientCpfpFunds
The funding provided for a unilateral exit can't cover its on-chain fees. required_satsrequired_satsrequiredSatsrequiredSatsrequiredSatsrequiredSatsrequiredSatsRequiredSatsRequiredSats is the minimum needed. See Troubleshooting.
TokenAllowance
A token allowance request was refused. reasonreasonreasonreasonreasonreasonreasonReasonReason says why, for example the amount is over a limit, the allowance was revoked or has expired, or a receiver isn't on its recipient list, and detailsdetailsdetailsdetailsdetailsdetailsdetailsDetailsDetails explains it further. See Token allowances.
Generic
Any other failure. The message describes what went wrong.