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
}