ckb_error/
lib.rs

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
105
106
107
108
109
110
111
112
113
114
115
//! Underlying error types used over ckb crates.

use std::{error::Error as StdError, fmt, ops::Deref, sync::Arc};

mod convert;
mod internal;
pub mod prelude;
pub mod util;

use derive_more::Display;
pub use internal::{InternalError, InternalErrorKind, OtherError, SilentError};
use prelude::*;

/// A wrapper around a dynamic error type.
#[derive(Clone)]
pub struct AnyError(Arc<anyhow::Error>);

/// A list specifying categories of ckb error.
///
/// This list is intended to grow over time and it is not recommended to exhaustively match against it.
///
/// It is used with [`Error`].
///
/// [`Error`]: ./struct.Error.html
#[derive(Debug, Clone, Copy, Eq, PartialEq, Display)]
pub enum ErrorKind {
    /// It indicates that the underlying error is [`OutPointError`].
    ///
    /// [`OutPointError`]: ../ckb_types/core/error/enum.OutPointError.html
    OutPoint,
    /// It indicates that the underlying error is [`TransactionError`].
    ///
    /// [`TransactionError`]: ../ckb_verification/enum.TransactionError.html
    Transaction,
    /// It indicates that the underlying error is [`Reject`].
    ///
    /// [`Reject`]: ../ckb_tx_pool/error/enum.Reject.html
    SubmitTransaction,
    /// It indicates that the underlying error is [`TransactionScriptError`].
    ///
    /// [`TransactionScriptError`]: ../ckb_script/struct.TransactionScriptError.html
    Script,
    /// It indicates that the underlying error is [`HeaderError`].
    ///
    /// [`HeaderError`]: ../ckb_verification/struct.HeaderError.html
    Header,
    /// It indicates that the underlying error is [`BlockError`]
    ///
    /// [`BlockError`]: ../ckb_verification/struct.BlockError.html
    Block,
    /// It indicates that the underlying error is [`InternalError`]
    ///
    /// [`InternalError`]: ./struct.InternalError.html
    Internal,
    /// It indicates that the underlying error is [`DaoError`]
    ///
    /// [`DaoError`]: ../ckb_types/core/error/enum.OutPointError.html
    Dao,
    /// It indicates that the underlying error is [`SpecError`]
    ///
    /// [`SpecError`]: ../ckb_chain_spec/enum.SpecError.html
    Spec,
}

def_error_base_on_kind!(Error, ErrorKind, "Top-level ckb error type.");

impl<E> From<E> for AnyError
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Self(Arc::new(error.into()))
    }
}

impl Deref for AnyError {
    type Target = Arc<anyhow::Error>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl fmt::Display for AnyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::Debug for AnyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}
/// Return whether the error's kind is `InternalErrorKind::Database`
///
/// ### Panic
///
/// Panic if the error kind is `InternalErrorKind::DataCorrupted`.
/// If the database is corrupted, panic is better than handle it silently.
pub fn is_internal_db_error(error: &Error) -> bool {
    if error.kind() == ErrorKind::Internal {
        let error_kind = error
            .downcast_ref::<InternalError>()
            .expect("error kind checked")
            .kind();
        if error_kind == InternalErrorKind::DataCorrupted {
            panic!("{}", error)
        } else {
            return error_kind == InternalErrorKind::Database
                || error_kind == InternalErrorKind::System;
        }
    }
    false
}