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
// Copyright 2021-2023 Protocol Labs
// Copyright 2019-2022 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use std::error::Error as StdError;

use fvm_ipld_encoding::Error as EncodingError;
use thiserror::Error;

/// HAMT Error
#[derive(Debug, Error)]
pub enum Error {
    /// Maximum depth error
    #[error("Maximum depth reached")]
    MaxDepth,
    /// Hash bits does not support greater than 8 bit width
    #[error("HashBits does not support retrieving more than 8 bits")]
    InvalidHashBitLen,
    /// This should be treated as a fatal error, must have at least one pointer in node
    #[error("Invalid HAMT format, node cannot have 0 pointers")]
    ZeroPointers,
    /// Cid not found in store error
    #[error("Cid ({0}) did not match any in database")]
    CidNotFound(String),
    #[error("Iteration starting key not found in HAMT")]
    StartKeyNotFound,
    /// Dynamic error for when the error needs to be forwarded as is.
    #[error("{0}")]
    Dynamic(anyhow::Error),
}

impl From<String> for Error {
    fn from(e: String) -> Self {
        Self::Dynamic(anyhow::anyhow!(e))
    }
}

impl From<&'static str> for Error {
    fn from(e: &'static str) -> Self {
        Self::Dynamic(anyhow::anyhow!(e))
    }
}

impl From<anyhow::Error> for Error {
    fn from(e: anyhow::Error) -> Self {
        e.downcast::<Error>().unwrap_or_else(Self::Dynamic)
    }
}

impl From<EncodingError> for Error {
    fn from(e: EncodingError) -> Self {
        Self::Dynamic(anyhow::anyhow!(e))
    }
}

impl From<Box<dyn StdError + Send + Sync>> for Error {
    fn from(e: Box<dyn StdError + Send + Sync>) -> Self {
        Self::Dynamic(anyhow::anyhow!(e))
    }
}