1use crate::pok_sig::PoKOfSignatureProofStatus;
2use crate::pok_vc::PoKVCError;
3use failure::{Backtrace, Context, Fail};
4#[cfg(feature = "wasm")]
5use wasm_bindgen::prelude::*;
6
7pub mod prelude {
9 pub use super::{BBSError, BBSErrorExt, BBSErrorKind};
10}
11
12#[derive(Debug, Fail, Clone)]
14pub enum BBSErrorKind {
15 #[fail(display = "Key Generation Error")]
17 KeyGenError,
18 #[fail(
20 display = "Public key to message mismatch. Expected {}, found {}",
21 0, 0
22 )]
23 PublicKeyGeneratorMessageCountMismatch(usize, usize),
24 #[fail(display = "Signature incorrect size. Expected 193, found {}", 0)]
26 SignatureIncorrectSize(usize),
27 #[fail(display = "Signature cannot be loaded due to a bad value")]
29 SignatureValueIncorrectSize,
30 #[fail(display = "Malformed public key")]
32 MalformedPublicKey,
33 #[fail(display = "Error from PoKVC module {:?}", msg)]
35 PoKVCError {
36 msg: String,
38 },
39 #[fail(display = "Invalid number of bytes. Expected {}, found {}", 0, 0)]
41 InvalidNumberOfBytes(usize, usize),
42 #[fail(display = "The proof failed due to {}", status)]
44 InvalidProof {
45 status: PoKOfSignatureProofStatus,
47 },
48 #[fail(display = "{:?}", msg)]
50 GeneralError {
51 msg: String,
53 },
54}
55
56#[derive(Debug)]
58pub struct BBSError {
59 inner: Context<BBSErrorKind>,
60}
61
62impl Fail for BBSError {
63 fn cause(&self) -> Option<&dyn Fail> {
64 self.inner.cause()
65 }
66
67 fn backtrace(&self) -> Option<&Backtrace> {
68 self.inner.backtrace()
69 }
70}
71
72impl BBSError {
73 pub fn from_msg<D>(kind: BBSErrorKind, msg: D) -> Self
75 where
76 D: std::fmt::Display + std::fmt::Debug + Send + Sync + 'static,
77 {
78 BBSError {
79 inner: Context::new(msg).context(kind),
80 }
81 }
82
83 pub fn from_kind(kind: BBSErrorKind) -> Self {
85 BBSError {
86 inner: Context::new("").context(kind),
87 }
88 }
89
90 pub fn kind(&self) -> BBSErrorKind {
92 self.inner.get_context().clone()
93 }
94}
95
96impl From<BBSErrorKind> for BBSError {
97 fn from(error: BBSErrorKind) -> Self {
98 BBSError::from_kind(error)
99 }
100}
101
102impl From<std::io::Error> for BBSError {
103 fn from(err: std::io::Error) -> BBSError {
104 BBSError::from_kind(BBSErrorKind::GeneralError {
105 msg: format!("{:?}", err),
106 })
107 }
108}
109
110impl std::fmt::Display for BBSError {
111 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112 let mut first = true;
113
114 for cause in Fail::iter_chain(&self.inner) {
115 if first {
116 first = false;
117 writeln!(f, "Error: {}", cause)?;
118 } else {
119 writeln!(f, "Caused by: {}", cause)?;
120 }
121 }
122
123 Ok(())
124 }
125}
126
127#[cfg(feature = "wasm")]
128impl From<BBSError> for JsValue {
129 fn from(error: BBSError) -> Self {
130 JsValue::from_str(&format!("{}", error))
131 }
132}
133
134#[cfg(feature = "wasm")]
135impl From<JsValue> for BBSError {
136 fn from(js: JsValue) -> Self {
137 if js.is_string() {
138 BBSError::from(BBSErrorKind::GeneralError {
139 msg: js.as_string().unwrap(),
140 })
141 } else {
142 BBSError::from(BBSErrorKind::GeneralError {
143 msg: "".to_string(),
144 })
145 }
146 }
147}
148
149#[cfg(feature = "wasm")]
150impl From<serde_wasm_bindgen::Error> for BBSError {
151 fn from(err: serde_wasm_bindgen::Error) -> Self {
152 BBSError::from(BBSErrorKind::GeneralError {
153 msg: format!("{:?}", err),
154 })
155 }
156}
157
158#[cfg(feature = "wasm")]
159impl From<BBSError> for serde_wasm_bindgen::Error {
160 fn from(err: BBSError) -> Self {
161 serde_wasm_bindgen::Error::new(err)
162 }
163}
164
165pub fn err_msg<D>(kind: BBSErrorKind, msg: D) -> BBSError
167where
168 D: std::fmt::Display + std::fmt::Debug + Send + Sync + 'static,
169{
170 BBSError::from_msg(kind, msg)
171}
172
173impl From<Context<BBSErrorKind>> for BBSError {
174 fn from(inner: Context<BBSErrorKind>) -> BBSError {
175 BBSError { inner }
176 }
177}
178
179pub trait BBSErrorExt {
181 fn to_bbs<D>(self, kind: BBSErrorKind, msg: D) -> BBSError
183 where
184 D: std::fmt::Display + Send + Sync + 'static;
185}
186
187impl<E> BBSErrorExt for E
188where
189 E: Fail,
190{
191 fn to_bbs<D>(self, kind: BBSErrorKind, msg: D) -> BBSError
192 where
193 D: std::fmt::Display + Send + Sync + 'static,
194 {
195 self.context(msg).context(kind).into()
196 }
197}
198
199impl From<PoKVCError> for BBSError {
200 fn from(err: PoKVCError) -> Self {
201 let message = format!(
202 "PoKVCError: {}",
203 Fail::iter_causes(&err)
204 .map(|e| e.to_string())
205 .collect::<String>()
206 );
207
208 BBSError::from_kind(BBSErrorKind::PoKVCError { msg: message })
209 }
210}