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
use crate::{
    blockcfg, blockchain,
    blockchain::StorageError,
    diagnostic::DiagnosticError,
    network, secure,
    settings::{self, logging},
};
use chain_core::property::ReadError;
use std::io;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum ErrorKind {
    #[error("block storage")]
    BlockStorage,
    #[error("Block0")]
    Block0,
}

#[derive(Debug, Error)]
pub enum Error {
    #[error("Unable to initialize the logger")]
    LoggingInitializationError(#[from] logging::Error),
    #[error("Error in the overall configuration of the node")]
    ConfigurationError(#[from] settings::Error),
    #[error("I/O Error with {reason}")]
    Io {
        #[source]
        source: io::Error,
        reason: ErrorKind,
    },
    #[error("Parsing error on {reason}")]
    ParseError {
        #[source]
        source: ReadError,
        reason: ErrorKind,
    },
    #[error("Block 0 mismatch. expecting hash: {expected} but got : {got}")]
    Block0Mismatch {
        expected: blockcfg::HeaderId,
        got: blockcfg::HeaderId,
    },
    #[error("Storage error")]
    StorageError(#[from] StorageError),
    #[error("Error while loading the legacy blockchain state")]
    Blockchain(#[from] Box<blockchain::Error>),
    #[error("Error in the genesis-block")]
    Block0(#[from] blockcfg::Block0Error),
    #[error("Error fetching the genesis block from the network")]
    FetchBlock0(#[from] network::FetchBlockError),
    #[error("Error while loading the blockchain from the network")]
    NetworkBootstrapError(#[source] network::BootstrapError),
    #[error("Error while loading the node's secrets.")]
    NodeSecrets(#[from] secure::NodeSecretFromFileError),
    #[error("Block 0 is set to start in the future")]
    Block0InFuture,
    #[error("A service has terminated with an error")]
    ServiceTerminatedWithError(#[from] crate::utils::task::ServiceError),
    #[error("Unable to get system limits: {0}")]
    DiagnosticError(#[from] DiagnosticError),
    #[error("Interrupted by the user")]
    Interrupted,
    #[error("Failed to create global state: {0}")]
    GlobalState(crate::network::NewGlobalStateError),
}

impl From<network::BootstrapError> for Error {
    fn from(error: network::BootstrapError) -> Error {
        match error {
            network::BootstrapError::Interrupted => Error::Interrupted,
            error => Error::NetworkBootstrapError(error),
        }
    }
}

impl Error {
    #[inline]
    pub fn code(&self) -> i32 {
        match self {
            Error::Interrupted => 0,
            Error::LoggingInitializationError { .. } => 1,
            Error::ConfigurationError { .. } => 2,
            Error::Io { .. } => 3,
            Error::ParseError { .. } => 4,
            Error::StorageError { .. } => 5,
            Error::Blockchain { .. } => 6,
            Error::Block0 { .. } => 7,
            Error::Block0Mismatch { .. } => 7,
            Error::Block0InFuture => 7,
            Error::NodeSecrets { .. } => 8,
            Error::FetchBlock0 { .. } => 9,
            Error::NetworkBootstrapError { .. } => 10,
            Error::ServiceTerminatedWithError { .. } => 12,
            Error::DiagnosticError { .. } => 13,
            Error::GlobalState(..) => 14,
        }
    }
}