#[error_code] y require!
Los enums #[error_code] se mapean a códigos de error estables en el IDL. require! y similares asertan condiciones con esos errores.
Receta
#[error_code]
pub enum MyError {
#[msg("El monto debe ser positivo")]
InvalidAmount,
}
require!(amount > 0, MyError::InvalidAmount);
require_eq!(owner, ctx.accounts.authority.key(), MyError::Unauthorized);Cuándo usar esto: Necesitas fallos tipados y decodificables por el cliente.
Ejemplo Funcional
#[error_code]
pub enum VaultError {
#[msg("La bóveda está pausada")]
Paused,
#[msg("Saldo insuficiente")]
InsufficientFunds,
#[msg("Desbordamiento matemático")]
Overflow,
}
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
require!(!ctx.accounts.vault.paused, VaultError::Paused);
require!(ctx.accounts.vault.balance >= amount, VaultError::InsufficientFunds);
ctx.accounts.vault.balance = ctx.accounts.vault.balance
.checked_sub(amount)
.ok_or(VaultError::Overflow)?;
Ok(())
}Lo que esto demuestra:
- Los errores aparecen en el IDL para los clientes
#[msg]establece texto legible por humanosrequire_eq!compara valores- Usa
Result?para mapear errores de CPI
Profundización
Macros
| Macro | Uso |
|---|---|
require! | Condición booleana |
require_eq! / require_ne! | Comprobaciones de igualdad |
require_keys_eq! | Comparaciones de Pubkey |
Anchor asigna códigos de error a partir de un desplazamiento personalizado; los clientes decodifican a través del IDL.
Trampas Comunes
- Raw ProgramError::Custom - Los clientes pierden el mapeo del IDL. Solución: Usa
#[error_code]. - Mensajes de error duplicados - Confunden al usuario. Solución: Una variante por fallo distinto.
requireen bucles ajustados - El costo de CU se acumula. Solución: Valida una vez antes del bucle.- Filtrar estado interno en
msg- Fuga de información de seguridad. Solución: Mantén los mensajes seguros para el usuario. - Olvidar
?en CPI - El error se traga. Solución: Propaga con?omap_err.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| constraint @ Error | Tiempo de validación de cuenta | Reglas de negocio del manejador |
| Errores personalizados nativos | No-Anchor | Clientes integrados con IDL |
Preguntas Frecuentes
¿Formato de error de Anchor 0.32.1?
Códigos personalizados en IDL más cadenas #[msg].
¿emit! vs emit_cpi!?
emit_cpi! cuesta más CU pero mejora la fiabilidad de la captura.
¿Debo usar msg! en mainnet?
Evítalo excepto detrás de flags de características.
¿Cómo obtienen los clientes los códigos de error?
Desde el IDL a través de Anchor o la generación de código de Codama.
¿Los eventos aparecen en el IDL?
Sí, los tipos #[event] se listan.
¿Pueden las restricciones devolver errores personalizados?
Sí, con @ MyError::Variant.
¿Qué usa CU en el registro?
Cada línea de registro y cadena formateada.
¿Cómo probar errores?
anchor test esperando códigos de error.
¿Son los registros datos de consenso?
Sí, pero no un contrato de API; usa eventos.
¿Próxima lectura?
Ver Relacionados para errores.
Relacionados
- Mensajes de Error Personalizados - mensajes
- Decodificación de Errores del Lado del Cliente - decodificación TS
- Conceptos Básicos de Errores de Programa - errores nativos
Versiones de Stack: Esta página fue escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, y LiteSVM 0.6.x.