Macros for implementing error-based traits on enums.
#[derive(IntoProgramError)]
: automatically derives the trait From<Self> for solana_program::program_error::ProgramError
.#[derive(DecodeError)]
: automatically derives the trait solana_program::decode_error::DecodeError<T>
.#[derive(PrintProgramError)]
: automatically derives the trait solana_program::program_error::PrintProgramError
.#[spl_program_error]
: Automatically derives all below traits:
Clone
Debug
Eq
DecodeError
IntoProgramError
PrintProgramError
thiserror::Error
num_derive::FromPrimitive
PartialEq
#[derive(IntoProgramError)]
This derive macro automatically derives the trait From<Self> for solana_program::program_error::ProgramError
.
Your enum must implement the following traits in order for this macro to work:
Clone
Debug
Eq
thiserror::Error
num_derive::FromPrimitive
PartialEq
Sample code:
```rust /// Example error
Clone, Debug, Eq, IntoProgramError, thiserror::Error, num_derive::FromPrimitive, PartialEq,
)] pub enum ExampleError { /// Mint has no mint authority #[error("Mint has no mint authority")] MintHasNoMintAuthority, /// Incorrect mint authority has signed the instruction #[error("Incorrect mint authority has signed the instruction")] IncorrectMintAuthority, } ```
#[derive(DecodeError)]
This derive macro automatically derives the trait solana_program::decode_error::DecodeError<T>
.
Your enum must implement the following traits in order for this macro to work:
Clone
Debug
Eq
IntoProgramError
(above)thiserror::Error
num_derive::FromPrimitive
PartialEq
Sample code:
```rust /// Example error
Clone,
Debug,
DecodeError,
Eq,
IntoProgramError,
thiserror::Error,
num_derive::FromPrimitive,
PartialEq,
)] pub enum ExampleError { /// Mint has no mint authority #[error("Mint has no mint authority")] MintHasNoMintAuthority, /// Incorrect mint authority has signed the instruction #[error("Incorrect mint authority has signed the instruction")] IncorrectMintAuthority, } ```
#[derive(PrintProgramError)]
This derive macro automatically derives the trait solana_program::program_error::PrintProgramError
.
Your enum must implement the following traits in order for this macro to work:
Clone
Debug
DecodeError<T>
(above)Eq
IntoProgramError
(above)thiserror::Error
num_derive::FromPrimitive
PartialEq
Sample code:
```rust /// Example error
Clone,
Debug,
DecodeError,
Eq,
IntoProgramError,
thiserror::Error,
num_derive::FromPrimitive,
PartialEq,
)] pub enum ExampleError { /// Mint has no mint authority #[error("Mint has no mint authority")] MintHasNoMintAuthority, /// Incorrect mint authority has signed the instruction #[error("Incorrect mint authority has signed the instruction")] IncorrectMintAuthority, } ```
#[spl_program_error]
It can be cumbersome to ensure your program's defined errors - typically represented in an enum - implement the required traits and will print to the program's logs when they're invoked.
This procedureal macro will give you all of the required implementations out of the box:
Clone
Debug
Eq
thiserror::Error
num_derive::FromPrimitive
PartialEq
It also imports the required crates so you don't have to in your program:
num_derive
num_traits
thiserror
Just annotate your enum...
```rust use solanaprogramerror_derive::*;
/// Example error
pub enum ExampleError { /// Mint has no mint authority #[error("Mint has no mint authority")] MintHasNoMintAuthority, /// Incorrect mint authority has signed the instruction #[error("Incorrect mint authority has signed the instruction")] IncorrectMintAuthority, } ```
...and get:
```rust /// Example error pub enum ExampleError { /// Mint has no mint authority #[error("Mint has no mint authority")] MintHasNoMintAuthority, /// Incorrect mint authority has signed the instruction #[error("Incorrect mint authority has signed the instruction")] IncorrectMintAuthority, }
impl ::core::clone::Clone for ExampleError { #[inline] fn clone(&self) -> ExampleError { match self { ExampleError::MintHasNoMintAuthority => ExampleError::MintHasNoMintAuthority, ExampleError::IncorrectMintAuthority => ExampleError::IncorrectMintAuthority, } } }
impl ::core::fmt::Debug for ExampleError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::write_str( f, match self { ExampleError::MintHasNoMintAuthority => "MintHasNoMintAuthority", ExampleError::IncorrectMintAuthority => "IncorrectMintAuthority", }, ) } }
impl ::core::marker::StructuralEq for ExampleError {}
impl ::core::cmp::Eq for ExampleError { #[inline] #[doc(hidden)] #[nocoverage] fn assertreceiveristotal_eq(&self) -> () {} }
impl std::error::Error for ExampleError {}
impl std::fmt::Display for ExampleError { fn fmt(&self, _formatter: &mut std::fmt::Formatter) -> std::fmt::Result { #[allow(unusedvariables, deprecated, clippy::usedunderscorebinding)] match self { ExampleError::MintHasNoMintAuthority {} => { _formatter.writefmt(formatargs!("Mint has no mint authority")) } ExampleError::IncorrectMintAuthority {} => { _formatter .writefmt( formatargs!( "Incorrect mint authority has signed the instruction" ), ) } } } }
const IMPLNUMFromPrimitiveFORExampleError: () = {
#[allow(clippy::uselessattribute)]
#[allow(rust2018idioms)]
extern crate numtraits as _numtraits;
impl numtraits::FromPrimitive for ExampleError {
#[allow(trivialnumericcasts)]
#[inline]
fn fromi64(n: i64) -> Option
impl ::core::marker::StructuralPartialEq for ExampleError {}
impl ::core::cmp::PartialEq for ExampleError {
#[inline]
fn eq(&self, other: &ExampleError) -> bool {
let _selftag = ::core::intrinsics::discriminantvalue(self);
let _arg1tag = ::core::intrinsics::discriminantvalue(other);
_selftag == _arg1tag
}
}
impl From