Las transacciones fallidas de Solana dejan pistas en los registros de simulación, los códigos de error RPC y la salida del programa del explorador. Un flujo de trabajo de decodificación disciplinado separa los errores del usuario, los errores del cliente, los problemas de RPC y los defectos del programa en la cadena antes de que reintentes o contactes al personal de guardia.
Simulación de preflight ejecuta la transacción contra el estado actual del ledger antes de la transmisión (cuando está habilitada en sendTransaction).
Los registros del programa se emiten a través de sol_log / msg! / anchor_lang::prelude::* y aparecen en la simulación y en los metadatos de las transacciones confirmadas.
Los errores personalizados del programa se codifican como InstructionError::Custom(u32) - mapea a tu IDL o enum #[error_code].
El presupuesto de cómputo por defecto es 200,000 CUs por instrucción a menos que antepongas instrucciones de ComputeBudget.
Los desajustes de metadatos de cuenta fallan antes de la ejecución: indicador de firma incorrecto, indicador de escritura incorrecto o cuenta faltante.
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]);}
// Anchor 0.32.1 - los errores aparecen como códigos personalizados en los logs#[error_code]pub enum MyError { #[msg("Vault is paused")] VaultPaused,}// Mapeo: anchor error --program-id <PID> muestra el código -> nombre
Reintentar sin leer los logs - Los usuarios envían repetidamente; quemas tarifas de prioridad en la misma falla determinista. Solución: Simula una vez, clasifica el error, corrige la causa raíz.
RPC del clúster incorrecto - Una transacción de Devnet simulada contra un RPC de Mainnet devuelve AccountNotFound. Solución: Fija RPC_URL, la red de la billetera y el ?cluster= del explorador juntos.
Asumir que preflight siempre está activado - Algunas rutas del servidor desactivan preflight por latencia. Solución:simulateTransaction explícito en herramientas de soporte.
Cantidades decimales vs lamports - El cliente envía 1.5 SOL como flotante; el programa espera lamports enteros. Solución:bigint de extremo a extremo; convierte solo en el límite de la UI.
Mapa de errores de IDL obsoleto - Programa v2 desplegado, el cliente aún decodifica códigos v1. Solución: Versiona el IDL en CI; regenera los clientes en cada lanzamiento del programa.
Ignorar unitsConsumed - Los programas cercanos al límite fallan solo bajo carga. Solución: Rastrea las CUs en métricas; alerta cuando el p95 excede el 80% del presupuesto.
No para envíos dirigidos al usuario. Mantén preflight activado a menos que tengas una razón de latencia medida y simulación del lado del servidor como respaldo.
¿Dónde aparecen los logs `msg!` de Anchor?
En los logs de simulación y en los metadatos de la transacción confirmada a través del RPC getTransaction.
¿Cómo decodifico `Custom: 6003`?
Ejecuta anchor error 6003 contra el IDL de tu programa, o lee el orden del enum #[error_code] (los códigos comienzan en 6000 en Anchor).
¿Qué pasa si la simulación tiene éxito pero el envío falla?
Probablemente expiración del blockhash, caída de red o omisión del líder. Actualiza el blockhash, verifica el estado de la firma e inspecciona si la transacción aterrizó en un slot posterior.
¿`sigVerify: false` oculta errores de firma?
Sí. Usa sigVerify: true al depurar problemas de firmante y pagador de tarifas; usa false solo al probar la lógica del programa con fixtures sin firmar.
¿Cómo capturo logs en una ruta de API de Next.js?
Simula del lado del servidor con @solana/kit, devuelve { err, logs, unitsConsumed } estructurado al cliente; nunca expongas claves de firma.
¿Cuál es el límite predeterminado de unidades de cómputo?
200,000 CUs por instrucción a menos que lo aumentes con ComputeBudgetInstruction::set_compute_unit_limit.
¿Puede una instrucción fallida revertir toda la transacción?
Sí. Las transacciones de Solana son atómicas a menos que tu programa capture errores de CPI internamente.
¿Cómo correlaciono errores entre proveedores RPC?
Registra la firma, el slot, la hora del bloque, el nombre del proveedor y el JSON del error. Compara getTransaction entre un proveedor secundario.
¿Cuándo debo contactar al equipo del programa en lugar del equipo del cliente?
Custom: N de tu ID de programa -> programa. AccountNotFound en el ATA del usuario -> cliente. RPC 429/503 -> infraestructura.