Transações Solana que falham deixam pistas em logs de simulação, códigos de erro RPC e output de programa em explorers. Um fluxo disciplinado de decode separa erros de usuário, bugs de client, problemas de RPC e defeitos de programa on-chain antes de você fazer retry ou acionar on-call.
function parseCustomError(logs: string[]): number | null { const line = logs.find((l) => l.includes("custom program error:")); if (!line) return null; const m = line.match(/custom program error: (0x[0-9a-f]+|\d+)/i); if (!m) return null; return m[1].startsWith("0x") ? parseInt(m[1], 16) : Number(m[1]);}
Retry sem ler logs - Usuários martelam resubmit; você queima priority fees na mesma falha determinística. Correção: Simule uma vez, classifique erro, corrija causa raiz.
RPC de cluster errado - Tx devnet simulada contra RPC mainnet retorna AccountNotFound. Correção: Fixe RPC_URL, rede da wallet e explorer ?cluster= juntos.
Assumir que preflight está sempre ligado - Alguns caminhos de servidor desligam preflight por latência. Correção:simulateTransaction explícito em tooling de suporte.
Decimais vs lamports - Client envia 1.5 SOL como float; programa espera lamports inteiros. Correção:bigint ponta a ponta; converta apenas na borda da UI.
Mapa de erros IDL obsoleto - Programa v2 implantado, client ainda decodifica códigos v1. Correção: Versione IDL em CI; regenere clients a cada release de programa.
Ignorar unitsConsumed - Programas perto do limite falham só sob carga. Correção: Rastreie CU em métricas; alerte quando p95 exceder 80% do budget.
Não para envios voltados ao usuário. Mantenha preflight ligado a menos que tenha motivo de latência medido e simulação server-side como rede de segurança.
Onde aparecem logs `msg!` do Anchor?
Em logs de simulação e na metadata de transação confirmada via RPC getTransaction.
Como decodificar `Custom: 6003`?
Execute anchor error 6003 contra seu IDL de programa, ou leia a ordem do enum #[error_code] (códigos começam em 6000 no Anchor).
E se simulação passar mas send falhar?
Provavelmente expiração de blockhash, queda de rede ou skip de leader. Atualize blockhash, verifique status da signature e inspecione se a tx pousou em slot posterior.
`sigVerify: false` esconde bugs de assinatura?
Sim. Use sigVerify: true ao depurar signer e fee payer; use false apenas ao testar lógica de programa com fixtures não assinadas.
Como capturar logs em rota API Next.js?
Simule server-side com @solana/kit, retorne { err, logs, unitsConsumed } estruturado ao client - nunca exponha signing keys.
Qual o limite padrão de compute units?
200.000 CUs por instruction a menos que você aumente com ComputeBudgetInstruction::set_compute_unit_limit.
Uma instruction falhando pode reverter a transação inteira?
Sim. Transações Solana são atômicas a menos que seu programa capture erros de CPI internamente.
Como correlacionar erros entre provedores RPC?
Logue signature, slot, block time, nome do provedor e JSON de erro. Compare getTransaction em provedor secundário.
Quando acionar time de programa vs time de client?
Custom: N do seu program ID -> programa. AccountNotFound em ATA do usuário -> client. RPC 429/503 -> infra.