canic_core/
lib.rs

1//! CANIC crate utilities for multi-canister apps on the Internet Computer.
2pub mod auth;
3pub mod config;
4pub mod env;
5pub mod guard;
6pub mod ids;
7pub mod interface;
8pub mod log;
9pub mod macros;
10pub mod model;
11pub mod ops;
12pub mod spec;
13
14pub use ::canic_cdk as cdk;
15pub use ::canic_macros::{impl_storable_bounded, impl_storable_unbounded, perf, perf_start};
16pub use ::canic_memory::{eager_init, eager_static, ic_memory, ic_memory_range};
17pub use ::canic_types as types;
18pub use ::canic_utils as utils;
19
20pub mod export {
21    pub use ::ctor;
22}
23
24pub use thiserror::Error as ThisError;
25
26use crate::cdk::{
27    call::{CallFailed, CandidDecodeFailed, Error as CallError},
28    candid::{CandidType, Error as CandidError},
29};
30use serde::Deserialize;
31
32///
33/// Crate Version
34///
35
36pub const CRATE_NAME: &str = env!("CARGO_PKG_NAME");
37pub const VERSION: &str = env!("CARGO_PKG_VERSION");
38
39///
40/// Error
41///
42/// top level error should handle all sub-errors, but not expose the child candid types
43///
44
45#[derive(CandidType, Debug, Deserialize, ThisError)]
46pub enum Error {
47    #[error("{0}")]
48    AuthError(String),
49
50    #[error("{0}")]
51    ConfigError(String),
52
53    #[error("{0}")]
54    CustomError(String),
55
56    #[error("{0}")]
57    EnvError(String),
58
59    #[error("{0}")]
60    InterfaceError(String),
61
62    #[error("{0}")]
63    ModelError(String),
64
65    #[error("{0}")]
66    OpsError(String),
67
68    #[error("{0}")]
69    SerializeError(String),
70
71    #[error("http request failed: {0}")]
72    HttpRequest(String),
73
74    #[error("http error status: {0}")]
75    HttpErrorCode(u32),
76
77    #[error("http decode failed: {0}")]
78    HttpDecode(String),
79
80    ///
81    /// Test Error
82    /// as we don't want to import dev-dependencies
83    ///
84
85    #[error("{0}")]
86    TestError(String),
87
88    ///
89    /// Common IC errors
90    ///
91    /// CallError          : should be automatic with ?
92    /// CallFailed         : use this for wrapping <T, String> return values
93    /// CandidError        : for decode_one errors etc.  automatic
94    /// CandidDecodeFailed : automatic for calls like ::candid<T>()
95    ///
96
97    #[error("call error: {0}")]
98    CallError(String),
99
100    #[error("call failed: {0}")]
101    CallFailed(String),
102
103    #[error("candid error: {0}")]
104    CandidError(String),
105
106    #[error("candid decode failed: {0}")]
107    CandidDecodeFailed(String),
108}
109
110macro_rules! from_to_string {
111    ($from:ty, $variant:ident) => {
112        impl From<$from> for Error {
113            fn from(e: $from) -> Self {
114                Error::$variant(e.to_string())
115            }
116        }
117    };
118}
119
120impl Error {
121    /// Build a custom error from a string without defining a new variant.
122    #[must_use]
123    pub fn custom<S: Into<String>>(s: S) -> Self {
124        Self::CustomError(s.into())
125    }
126
127    /// Build a test error to avoid extra dev-only dependencies.
128    #[must_use]
129    pub fn test<S: Into<String>>(s: S) -> Self {
130        Self::TestError(s.into())
131    }
132}
133
134from_to_string!(auth::AuthError, AuthError);
135from_to_string!(config::ConfigError, ConfigError);
136from_to_string!(env::EnvError, EnvError);
137from_to_string!(interface::InterfaceError, InterfaceError);
138from_to_string!(model::ModelError, ModelError);
139from_to_string!(ops::OpsError, OpsError);
140from_to_string!(serde_json::Error, HttpDecode);
141
142from_to_string!(CallError, CallError);
143from_to_string!(CallFailed, CallFailed);
144from_to_string!(CandidDecodeFailed, CandidDecodeFailed);
145from_to_string!(CandidError, CandidError);