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