ckb_error/
lib.rs

1//! Underlying error types used over ckb crates.
2
3use std::{error::Error as StdError, fmt, ops::Deref, sync::Arc};
4
5mod convert;
6mod internal;
7pub mod prelude;
8pub mod util;
9
10use derive_more::Display;
11pub use internal::{InternalError, InternalErrorKind, OtherError, SilentError};
12use prelude::*;
13
14/// A wrapper around a dynamic error type.
15#[derive(Clone)]
16pub struct AnyError(Arc<anyhow::Error>);
17
18/// A list specifying categories of ckb error.
19///
20/// This list is intended to grow over time and it is not recommended to exhaustively match against it.
21///
22/// It is used with [`Error`].
23///
24/// [`Error`]: ./struct.Error.html
25#[derive(Debug, Clone, Copy, Eq, PartialEq, Display)]
26pub enum ErrorKind {
27    /// It indicates that the underlying error is [`OutPointError`].
28    ///
29    /// [`OutPointError`]: ../ckb_types/core/error/enum.OutPointError.html
30    OutPoint,
31    /// It indicates that the underlying error is [`TransactionError`].
32    ///
33    /// [`TransactionError`]: ../ckb_verification/enum.TransactionError.html
34    Transaction,
35    /// It indicates that the underlying error is [`Reject`].
36    ///
37    /// [`Reject`]: ../ckb_tx_pool/error/enum.Reject.html
38    SubmitTransaction,
39    /// It indicates that the underlying error is [`TransactionScriptError`].
40    ///
41    /// [`TransactionScriptError`]: ../ckb_script/struct.TransactionScriptError.html
42    Script,
43    /// It indicates that the underlying error is [`HeaderError`].
44    ///
45    /// [`HeaderError`]: ../ckb_verification/struct.HeaderError.html
46    Header,
47    /// It indicates that the underlying error is [`BlockError`]
48    ///
49    /// [`BlockError`]: ../ckb_verification/struct.BlockError.html
50    Block,
51    /// It indicates that the underlying error is [`InternalError`]
52    ///
53    /// [`InternalError`]: ./struct.InternalError.html
54    Internal,
55    /// It indicates that the underlying error is [`DaoError`]
56    ///
57    /// [`DaoError`]: ../ckb_types/core/error/enum.OutPointError.html
58    Dao,
59    /// It indicates that the underlying error is [`SpecError`]
60    ///
61    /// [`SpecError`]: ../ckb_chain_spec/enum.SpecError.html
62    Spec,
63}
64
65def_error_base_on_kind!(Error, ErrorKind, "Top-level ckb error type.");
66
67impl<E> From<E> for AnyError
68where
69    E: StdError + Send + Sync + 'static,
70{
71    fn from(error: E) -> Self {
72        Self(Arc::new(error.into()))
73    }
74}
75
76impl Deref for AnyError {
77    type Target = Arc<anyhow::Error>;
78
79    fn deref(&self) -> &Self::Target {
80        &self.0
81    }
82}
83
84impl fmt::Display for AnyError {
85    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86        self.0.fmt(f)
87    }
88}
89
90impl fmt::Debug for AnyError {
91    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92        derive_more::Display::fmt(self, f)
93    }
94}
95/// Return whether the error's kind is `InternalErrorKind::Database`
96///
97/// ### Panic
98///
99/// Panic if the error kind is `InternalErrorKind::DataCorrupted`.
100/// If the database is corrupted, panic is better than handle it silently.
101pub fn is_internal_db_error(error: &Error) -> bool {
102    if error.kind() == ErrorKind::Internal {
103        let error_kind = error
104            .downcast_ref::<InternalError>()
105            .expect("error kind checked")
106            .kind();
107        if error_kind == InternalErrorKind::DataCorrupted {
108            panic!("{}", error)
109        } else {
110            return error_kind == InternalErrorKind::Database
111                || error_kind == InternalErrorKind::System;
112        }
113    }
114    false
115}