1use std::error::Error as StdError;
2use std::fmt;
3use std::result;
4use std::sync::Arc;
5
6pub fn new_error(kind: ErrorKind) -> Error {
9 Error(Box::new(kind))
10}
11
12pub type Result<T> = result::Result<T, Error>;
14
15#[derive(Clone, Debug, Eq, PartialEq)]
17pub struct Error(Box<ErrorKind>);
18
19impl Error {
20 pub fn kind(&self) -> &ErrorKind {
22 &self.0
23 }
24
25 pub fn into_kind(self) -> ErrorKind {
27 *self.0
28 }
29}
30
31#[non_exhaustive]
37#[derive(Clone, Debug)]
38pub enum ErrorKind {
39 InvalidToken,
41 InvalidSignature,
43 InvalidEcdsaKey,
45 InvalidEddsaKey,
47 InvalidRsaKey(String),
49 RsaFailedSigning,
51 Signing(String),
53 InvalidAlgorithmName,
55 UnsupportedAlgorithm,
57 InvalidKeyFormat,
59
60 MissingRequiredClaim(String),
63 InvalidClaimFormat(String),
65 ExpiredSignature,
67 InvalidIssuer,
69 InvalidAudience,
71 InvalidSubject,
73 ImmatureSignature,
75 InvalidAlgorithm,
78 MissingAlgorithm,
80
81 Base64(base64::DecodeError),
84 Json(Arc<serde_json::Error>),
86 Utf8(::std::string::FromUtf8Error),
88 Provider(String),
90}
91
92impl StdError for Error {
93 fn cause(&self) -> Option<&dyn StdError> {
94 match &*self.0 {
95 ErrorKind::InvalidToken => None,
96 ErrorKind::InvalidSignature => None,
97 ErrorKind::InvalidEcdsaKey => None,
98 ErrorKind::InvalidEddsaKey => None,
99 ErrorKind::RsaFailedSigning => None,
100 ErrorKind::Signing(_) => None,
101 ErrorKind::InvalidRsaKey(_) => None,
102 ErrorKind::ExpiredSignature => None,
103 ErrorKind::MissingAlgorithm => None,
104 ErrorKind::MissingRequiredClaim(_) => None,
105 ErrorKind::InvalidClaimFormat(_) => None,
106 ErrorKind::InvalidIssuer => None,
107 ErrorKind::InvalidAudience => None,
108 ErrorKind::InvalidSubject => None,
109 ErrorKind::ImmatureSignature => None,
110 ErrorKind::InvalidAlgorithm => None,
111 ErrorKind::UnsupportedAlgorithm => None,
112 ErrorKind::InvalidAlgorithmName => None,
113 ErrorKind::InvalidKeyFormat => None,
114 ErrorKind::Base64(err) => Some(err),
115 ErrorKind::Json(err) => Some(err.as_ref()),
116 ErrorKind::Utf8(err) => Some(err),
117 ErrorKind::Provider(_) => None,
118 }
119 }
120}
121
122impl fmt::Display for Error {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 match &*self.0 {
125 ErrorKind::InvalidToken
126 | ErrorKind::InvalidSignature
127 | ErrorKind::InvalidEcdsaKey
128 | ErrorKind::ExpiredSignature
129 | ErrorKind::RsaFailedSigning
130 | ErrorKind::MissingAlgorithm
131 | ErrorKind::InvalidIssuer
132 | ErrorKind::InvalidAudience
133 | ErrorKind::InvalidSubject
134 | ErrorKind::ImmatureSignature
135 | ErrorKind::InvalidAlgorithm
136 | ErrorKind::UnsupportedAlgorithm
137 | ErrorKind::InvalidKeyFormat
138 | ErrorKind::InvalidEddsaKey
139 | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
140 ErrorKind::MissingRequiredClaim(c) => write!(f, "Missing required claim: {}", c),
141 ErrorKind::InvalidClaimFormat(c) => write!(f, "Invalid format for claim: {}", c),
142 ErrorKind::InvalidRsaKey(msg) => write!(f, "RSA key invalid: {}", msg),
143 ErrorKind::Signing(msg) => write!(f, "Signing failed: {}", msg),
144 ErrorKind::Json(err) => write!(f, "JSON error: {}", err),
145 ErrorKind::Utf8(err) => write!(f, "UTF-8 error: {}", err),
146 ErrorKind::Base64(err) => write!(f, "Base64 error: {}", err),
147 ErrorKind::Provider(msg) => write!(f, "Custom provider error: {}", msg),
148 }
149 }
150}
151
152impl PartialEq for ErrorKind {
153 fn eq(&self, other: &Self) -> bool {
154 format!("{:?}", self) == format!("{:?}", other)
155 }
156}
157
158impl Eq for ErrorKind {}
160
161impl From<base64::DecodeError> for Error {
162 fn from(err: base64::DecodeError) -> Error {
163 new_error(ErrorKind::Base64(err))
164 }
165}
166
167impl From<serde_json::Error> for Error {
168 fn from(err: serde_json::Error) -> Error {
169 new_error(ErrorKind::Json(Arc::new(err)))
170 }
171}
172
173impl From<::std::string::FromUtf8Error> for Error {
174 fn from(err: ::std::string::FromUtf8Error) -> Error {
175 new_error(ErrorKind::Utf8(err))
176 }
177}
178
179impl From<ErrorKind> for Error {
180 fn from(kind: ErrorKind) -> Error {
181 new_error(kind)
182 }
183}
184
185impl From<signature::Error> for Error {
186 fn from(err: signature::Error) -> Error {
187 new_error(ErrorKind::Signing(err.to_string()))
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use wasm_bindgen_test::wasm_bindgen_test;
194
195 use super::*;
196
197 #[test]
198 #[wasm_bindgen_test]
199 fn test_error_rendering() {
200 assert_eq!(
201 "InvalidAlgorithmName",
202 Error::from(ErrorKind::InvalidAlgorithmName).to_string()
203 );
204 }
205}