1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! All errors that can occur within workspaces, including but not limited to
//! the following: IO, RPC, Execution, Sandbox, DataConversion errors.

pub(crate) mod execution;
mod impls;

use std::borrow::Cow;

use crate::result::ExecutionFailure;

/// A list specifying general categories of NEAR workspace error.
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum ErrorKind {
    /// An error occurred while performing an RPC request.
    #[error("{0}")]
    Rpc(#[from] RpcErrorCode),
    /// An error occurred while processing a transaction.
    #[error("Execution")]
    Execution,
    /// An error having to do with running sandbox.
    #[error("{0}")]
    Sandbox(#[from] SandboxErrorCode),
    /// An error from performing IO.
    #[error("IO")]
    Io,
    /// An error from converting data.
    #[error("DataConversion")]
    DataConversion,
    /// An error that cannot be categorized into the other error kinds.
    #[error("Other")]
    Other,
}

#[derive(Debug, thiserror::Error)]
enum ErrorRepr {
    #[error("{0}")]
    Simple(ErrorKind),
    #[error("{message}")]
    Message {
        kind: ErrorKind,
        message: Cow<'static, str>,
    },
    #[error("{kind}")]
    Custom {
        kind: ErrorKind,
        #[source]
        error: Box<dyn std::error::Error + Send + Sync>,
    },
    #[error("{message}")]
    Full {
        kind: ErrorKind,
        message: Cow<'static, str>,
        #[source]
        error: Box<dyn std::error::Error + Send + Sync>,
    },
    #[error("{error}")]
    Detailed {
        kind: ErrorKind,
        // NOTE: Box to mitigate large size difference between enum variants
        error: Box<ExecutionFailure>,
    },
}

/// Error type that workspaces will make use of for all the errors
/// returned from this library
#[derive(Debug)]
pub struct Error {
    repr: ErrorRepr,
}

#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum SandboxErrorCode {
    #[error("Sandbox has already been started")]
    AlreadyStarted,
    #[error("Could not initialize sandbox node")]
    InitFailure,
    #[error("Could not startup and run sandbox node")]
    RunFailure,
    #[error("Sandbox failed to patch state")]
    PatchStateFailure,
    #[error("Sandbox failed to fast forward")]
    FastForwardFailure,
}

#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum RpcErrorCode {
    #[error("unable to create a new account via helper")]
    HelperAccountCreationFailure,
    #[error("failed to connect to rpc service")]
    ConnectionFailure,
    #[error("access key was unable to be retrieved")]
    UnableToRetrieveAccessKey,
    #[error("unable to broadcast the transaction to the network")]
    BroadcastTxFailure,
    #[error("unable to call into a view function")]
    ViewFunctionFailure,
    #[error("unable to fulfill the query request")]
    QueryFailure,
    #[error("incorrect variant retrieved while querying (maybe a bug in RPC code?)")]
    QueryReturnedInvalidData,
}