自定义错误
学习如何在 Anchor 程序中实现自定义错误处理。
在 Anchor 程序中,所有指令处理程序都返回一个自定义的 Result<T>
类型,允许你通过 Ok(T)
处理成功执行,并通过 Err(Error)
处理错误情况。
在 Anchor 程序中,Result<T>
类型是一个类型别名,它封装了标准的 Rust Result<T, E>
。在这种情况下,T
表示成功的返回类型,而 E
则是 Anchor 的自定义 Error
类型。
Anchor 错误
当 Anchor 程序中发生错误时,它会返回一个自定义的 Error
类型,定义为:
Anchor 程序中的 Error
类型可以是以下两种变体之一:
ProgramErrorWithOrigin
:一种自定义类型,它封装了标准的 SolanaProgramError
类型。这些错误来自solana_program
crate。
AnchorError
:由 Anchor 框架定义的错误。
AnchorError
可以看作是具有以下两种类别:
-
内部 Anchor 错误 - 这些是 Anchor 框架内置的错误。它们在
ErrorCode
枚举中定义。 -
自定义程序错误 - 这些是开发者定义的特定于程序的错误,用于处理自定义错误情况。
AnchorError
的 error_code_number
具有以下编号方案:
错误代码 | 描述 |
---|---|
>= 100 | 指令错误代码 |
>= 1000 | IDL 错误代码 |
>= 2000 | 约束错误代码 |
>= 3000 | 账户错误代码 |
>= 4100 | 杂项错误代码 |
= 5000 | 已弃用的错误代码 |
>= 6000 | 自定义用户错误的起始点 |
使用
Anchor 提供了一种通过 error_code
属性定义自定义错误的便捷方法。实现细节可以在这里找到。
当你使用 error_code
属性定义一个枚举时,Anchor 会自动:
- 从 6000 开始分配错误代码
- 生成必要的错误处理样板代码
- 启用通过
msg
属性使用自定义错误消息
err!
要抛出错误,请使用 err!
宏。err!
宏提供了一种便捷的方式从程序中返回自定义错误。在底层,err!
使用 error!
宏来构建 AnchorError
。实现可以在这里找到。
require!
require!
宏提供了一种更简洁的方式来处理错误条件。它结合了条件检查和条件为假时返回错误的功能。以下是我们如何使用 require!
重写前面的示例:
Anchor 提供了几个 "require" 宏来满足不同的验证需求。你可以在这里找到这些宏的实现。
宏 | 描述 |
---|---|
require! | 确保条件为真,否则返回给定的错误。 |
require_eq! | 确保两个 NON-PUBKEY 值相等。 |
require_neq! | 确保两个 NON-PUBKEY 值不相等。 |
require_keys_eq! | 确保两个 pubkeys 值相等。 |
require_keys_neq! | 确保两个 pubkeys 值不相等。 |
require_gt! | 确保第一个 NON-PUBKEY 值大于第二个 NON-PUBKEY 值。 |
require_gte! | 确保第一个 NON-PUBKEY 值大于或等于第二个 NON-PUBKEY 值。 |
示例
以下是一个简单的示例,演示了如何在 Anchor 程序中定义和处理自定义错误。下面的程序验证输入金额是否在可接受范围内,展示了如何:
- 定义带有消息的自定义错误类型
- 使用
require!
宏检查条件并返回错误
当程序错误发生时,Anchor 的 TypeScript 客户端 SDK 返回一个详细的错误响应,其中包含有关错误的信息。以下是一个错误响应的示例,展示了结构和可用字段:
有关更全面的示例,你还可以参考 Anchor 仓库中的错误测试程序。