Cli error cleanup 1.0 (#8834)
* Don't use move semantics if not needed (#8793) * SDK: Deboilerplate `TransportError` with thiserror * Enable interchange between `TransportError` and `ClientError` * SDK: Retval consistency between `Client` and `AsyncClient` traits * Client: Introduce/use `Result` type * Client: Remove unused `RpcResponseIn` type * Client: Rename `RpcResponse` to more appropriate `RpcResult` * Client: Death to `io::Result` return types * Client: Struct-ify `ClientError` * Client: Add optional `command` parameter to `ClientError` * RpcClient: Stop abusing `io::Error` (low-fruit) * ClientError: Use `thiserror`'s `Display` impl * Extend `RpcError`'s utility * RpcClient: Stop abusing `io::Error` (the rest) * CLI: Shim `main()` so we can `Display` format errors * claputils: format input validator errors with `Display` They are intended to be displayed to users * SDK: `thiserror` for hash and sig parse erros * Keygen: Shim main to format errors with `Display` * SDK: `thiserror` for `InstructionError` * CLI: `thiserror` for `CliError` * CLI: Format user messages with `Display` * Client: Tweak `Display` for `ClientError` * RpcClient: Improve messaging when TX cannot be confirmed * fu death io res retval * CLI/Keygen - fix shell return value on error * Tweak `InstructionError` `Display` messages as per review * Cleanup hackjob return code fix * Embrace that which you hate most * Too much... Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
@@ -3,96 +3,124 @@
|
||||
use crate::{pubkey::Pubkey, short_vec, system_instruction::SystemError};
|
||||
use bincode::serialize;
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Reasons the runtime might have rejected an instruction.
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Error, PartialEq, Eq, Clone)]
|
||||
pub enum InstructionError {
|
||||
/// Deprecated! Use CustomError instead!
|
||||
/// The program instruction returned an error
|
||||
#[error("generic instruction error")]
|
||||
GenericError,
|
||||
|
||||
/// The arguments provided to a program instruction where invalid
|
||||
/// The arguments provided to a program were invalid
|
||||
#[error("invalid program argument")]
|
||||
InvalidArgument,
|
||||
|
||||
/// An instruction's data contents was invalid
|
||||
/// An instruction's data contents were invalid
|
||||
#[error("invalid instruction data")]
|
||||
InvalidInstructionData,
|
||||
|
||||
/// An account's data contents was invalid
|
||||
#[error("invalid account data for instruction")]
|
||||
InvalidAccountData,
|
||||
|
||||
/// An account's data was too small
|
||||
#[error("account data too small for instruction")]
|
||||
AccountDataTooSmall,
|
||||
|
||||
/// An account's balance was too small to complete the instruction
|
||||
#[error("insufficient funds for instruction")]
|
||||
InsufficientFunds,
|
||||
|
||||
/// The account did not have the expected program id
|
||||
#[error("incorrect program id for instruction")]
|
||||
IncorrectProgramId,
|
||||
|
||||
/// A signature was required but not found
|
||||
#[error("missing required signature for instruction")]
|
||||
MissingRequiredSignature,
|
||||
|
||||
/// An initialize instruction was sent to an account that has already been initialized.
|
||||
#[error("instruction requires an uninitialized account")]
|
||||
AccountAlreadyInitialized,
|
||||
|
||||
/// An attempt to operate on an account that hasn't been initialized.
|
||||
#[error("instruction requires an initialized account")]
|
||||
UninitializedAccount,
|
||||
|
||||
/// Program's instruction lamport balance does not equal the balance after the instruction
|
||||
#[error("sum of account balances before and after instruction do not match")]
|
||||
UnbalancedInstruction,
|
||||
|
||||
/// Program modified an account's program id
|
||||
#[error("instruction modified the program id of an account")]
|
||||
ModifiedProgramId,
|
||||
|
||||
/// Program spent the lamports of an account that doesn't belong to it
|
||||
#[error("instruction spent from the balance of an account it does not own")]
|
||||
ExternalAccountLamportSpend,
|
||||
|
||||
/// Program modified the data of an account that doesn't belong to it
|
||||
#[error("instruction modified data of an account it does not own")]
|
||||
ExternalAccountDataModified,
|
||||
|
||||
/// Read-only account modified lamports
|
||||
#[error("instruction changed balance of a read-only account")]
|
||||
ReadonlyLamportChange,
|
||||
|
||||
/// Read-only account modified data
|
||||
#[error("instruction modified data of a read-only account")]
|
||||
ReadonlyDataModified,
|
||||
|
||||
/// An account was referenced more than once in a single instruction
|
||||
// Deprecated, instructions can now contain duplicate accounts
|
||||
#[error("instruction contains duplicate accounts")]
|
||||
DuplicateAccountIndex,
|
||||
|
||||
/// Executable bit on account changed, but shouldn't have
|
||||
#[error("instruction changed executable bit of an account")]
|
||||
ExecutableModified,
|
||||
|
||||
/// Rent_epoch account changed, but shouldn't have
|
||||
#[error("instruction modified rent epoch of an account")]
|
||||
RentEpochModified,
|
||||
|
||||
/// The instruction expected additional account keys
|
||||
#[error("insufficient account key count for instruction")]
|
||||
NotEnoughAccountKeys,
|
||||
|
||||
/// A non-system program changed the size of the account data
|
||||
#[error("non-system instruction changed account size")]
|
||||
AccountDataSizeChanged,
|
||||
|
||||
/// The instruction expected an executable account
|
||||
#[error("instruction expected an executable account")]
|
||||
AccountNotExecutable,
|
||||
|
||||
/// Failed to borrow a reference to account data, already borrowed
|
||||
#[error("instruction tries to borrow reference for an account which is already borrowed")]
|
||||
AccountBorrowFailed,
|
||||
|
||||
/// Account data has an outstanding reference after a program's execution
|
||||
#[error("instruction left account with an outstanding reference borrowed")]
|
||||
AccountBorrowOutstanding,
|
||||
|
||||
/// The same account was multiply passed to an on-chain program's entrypoint, but the program
|
||||
/// modified them differently. A program can only modify one instance of the account because
|
||||
/// the runtime cannot determine which changes to pick or how to merge them if both are modified
|
||||
#[error("instruction modifications of multiply-passed account differ")]
|
||||
DuplicateAccountOutOfSync,
|
||||
|
||||
/// Allows on-chain programs to implement program-specific error types and see them returned
|
||||
/// by the Solana runtime. A program-specific error may be any type that is represented as
|
||||
/// or serialized to a u32 integer.
|
||||
#[error("program error: {0}")]
|
||||
CustomError(u32),
|
||||
|
||||
/// The return value from the program was invalid. Valid errors are either a defined builtin
|
||||
/// error value or a user-defined error in the lower 32 bits.
|
||||
#[error("program returned invalid error code")]
|
||||
InvalidError,
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user