Errors
SdkError variants plus typed AURA program error codes for the Rust SDK.
Pre-alpha — not production ready
aura-sdk targets Solana devnet only. APIs may change without notice. Do not use for real funds until a stable release and audit are published.
The SDK separates two concerns:
SdkError— failures the SDK itself surfaces (RPC transport, account decoding, missing payer, invalid parameters).program_errors— the 140 on-chainaura-coreerror codes, exposed as a typed table with helpers to parse them out of a failed transaction.
SdkError
use aura_sdk::SdkError;
pub enum SdkError {
/// Solana RPC returned an error.
Rpc(solana_client::client_error::ClientError),
/// The requested account does not exist on-chain.
AccountNotFound(Pubkey),
/// Anchor account decoding failed.
AccountDecode { account_name: &'static str, message: String },
/// Converting a treasury record back into the domain model failed.
DomainDecode(String),
/// The client was asked to submit a transaction without a configured payer.
MissingDefaultPayer,
/// A caller-supplied parameter was invalid before any RPC call was made.
InvalidParameter(String),
}SdkError implements std::error::Error, so it composes with anyhow:
use anyhow::{Context, Result};
fn fetch(client: &aura_sdk::AuraClient, pda: &solana_sdk::pubkey::Pubkey) -> Result<()> {
let treasury = client
.get_treasury(pda)
.with_context(|| format!("failed to fetch treasury {pda}"))?;
println!("agent: {}", treasury.agent_id);
Ok(())
}Program error codes
The program defines all on-chain failures in its Anchor #[error_code] enum,
[AuraCoreError], which is re-exported from the SDK. Anchor numbers each variant
from 6000 ([AURA_ERROR_CODE_OFFSET]); those are the custom program error
codes a failed transaction returns.
Every variant is mirrored in [AURA_PROGRAM_ERRORS] — a &[AuraProgramError]
table whose code is derived from the live enum, so it can never drift from the
deployed program.
pub struct AuraProgramError {
pub code: u32, // 6000-based on-chain code
pub name: &'static str, // AuraCoreError variant name
pub message: &'static str // the program's #[msg(...)] text
}program_error_by_code / program_error_by_name
use aura_sdk::{program_error_by_code, program_errors::program_error_by_name, AuraCoreError};
let info = program_error_by_code(6017).unwrap();
assert_eq!(info.name, "ExecutionPaused");
assert_eq!(info.code, AuraCoreError::ExecutionPaused as u32 + 6000);
let info = program_error_by_name("BatchTooLarge").unwrap();
assert_eq!(info.message, "batch proposal exceeds maximum item count");Iterate the full table for UI lookups or error dictionaries:
use aura_sdk::AURA_PROGRAM_ERRORS;
for error in AURA_PROGRAM_ERRORS {
println!("{} = {}: {}", error.code, error.name, error.message);
}parse_program_error
Resolves an [SdkError] into the underlying program error, parsing both Solana's
custom program error: 0x... form and Anchor's Error Number: ... log line.
Returns None when the failure isn't a recognized AURA program error.
use aura_sdk::parse_program_error;
match client.propose_transaction(&ai_authority, treasury, args) {
Ok(sig) => println!("submitted: {sig}"),
Err(error) => {
if let Some(program_error) = error.program_error() {
// `SdkError::program_error()` is shorthand for parse_program_error(&error)
eprintln!(
"rejected: {} (#{}) — {}",
program_error.name, program_error.code, program_error.message,
);
} else if let Some(info) = parse_program_error(&error) {
eprintln!("{info}");
} else {
eprintln!("client/RPC error: {error}");
}
}
}is_program_error
Boolean guard, optionally narrowed to a specific code:
use aura_sdk::{is_program_error, AuraCoreError};
if let Err(error) = client.propose_transaction(&ai_authority, treasury, args) {
if is_program_error(&error, AuraCoreError::ExecutionPaused as u32 + 6000) {
// treasury is paused — surface a resume action
}
}Failures that aren't AURA program errors (system program, compute budget, RPC
transport, etc.) return None/false from these helpers — handle those with
your normal SdkError matching.