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 InvalidKeyFormat,
57
58 MissingRequiredClaim(String),
61 InvalidClaimFormat(String),
63 ExpiredSignature,
65 InvalidIssuer,
67 InvalidAudience,
69 InvalidSubject,
71 ImmatureSignature,
73 InvalidAlgorithm,
76 MissingAlgorithm,
78
79 Base64(base64::DecodeError),
82 Json(Arc<serde_json::Error>),
84 Utf8(::std::string::FromUtf8Error),
86 Provider(String),
88}
89
90impl StdError for Error {
91 fn cause(&self) -> Option<&dyn StdError> {
92 match &*self.0 {
93 ErrorKind::InvalidToken => None,
94 ErrorKind::InvalidSignature => None,
95 ErrorKind::InvalidEcdsaKey => None,
96 ErrorKind::InvalidEddsaKey => None,
97 ErrorKind::RsaFailedSigning => None,
98 ErrorKind::Signing(_) => None,
99 ErrorKind::InvalidRsaKey(_) => None,
100 ErrorKind::ExpiredSignature => None,
101 ErrorKind::MissingAlgorithm => None,
102 ErrorKind::MissingRequiredClaim(_) => None,
103 ErrorKind::InvalidClaimFormat(_) => None,
104 ErrorKind::InvalidIssuer => None,
105 ErrorKind::InvalidAudience => None,
106 ErrorKind::InvalidSubject => None,
107 ErrorKind::ImmatureSignature => None,
108 ErrorKind::InvalidAlgorithm => None,
109 ErrorKind::InvalidAlgorithmName => None,
110 ErrorKind::InvalidKeyFormat => None,
111 ErrorKind::Base64(err) => Some(err),
112 ErrorKind::Json(err) => Some(err.as_ref()),
113 ErrorKind::Utf8(err) => Some(err),
114 ErrorKind::Provider(_) => None,
115 }
116 }
117}
118
119impl fmt::Display for Error {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 match &*self.0 {
122 ErrorKind::InvalidToken
123 | ErrorKind::InvalidSignature
124 | ErrorKind::InvalidEcdsaKey
125 | ErrorKind::ExpiredSignature
126 | ErrorKind::RsaFailedSigning
127 | ErrorKind::MissingAlgorithm
128 | ErrorKind::InvalidIssuer
129 | ErrorKind::InvalidAudience
130 | ErrorKind::InvalidSubject
131 | ErrorKind::ImmatureSignature
132 | ErrorKind::InvalidAlgorithm
133 | ErrorKind::InvalidKeyFormat
134 | ErrorKind::InvalidEddsaKey
135 | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
136 ErrorKind::MissingRequiredClaim(c) => write!(f, "Missing required claim: {}", c),
137 ErrorKind::InvalidClaimFormat(c) => write!(f, "Invalid format for claim: {}", c),
138 ErrorKind::InvalidRsaKey(msg) => write!(f, "RSA key invalid: {}", msg),
139 ErrorKind::Signing(msg) => write!(f, "Signing failed: {}", msg),
140 ErrorKind::Json(err) => write!(f, "JSON error: {}", err),
141 ErrorKind::Utf8(err) => write!(f, "UTF-8 error: {}", err),
142 ErrorKind::Base64(err) => write!(f, "Base64 error: {}", err),
143 ErrorKind::Provider(msg) => write!(f, "Custom provider error: {}", msg),
144 }
145 }
146}
147
148impl PartialEq for ErrorKind {
149 fn eq(&self, other: &Self) -> bool {
150 format!("{:?}", self) == format!("{:?}", other)
151 }
152}
153
154impl Eq for ErrorKind {}
156
157impl From<base64::DecodeError> for Error {
158 fn from(err: base64::DecodeError) -> Error {
159 new_error(ErrorKind::Base64(err))
160 }
161}
162
163impl From<serde_json::Error> for Error {
164 fn from(err: serde_json::Error) -> Error {
165 new_error(ErrorKind::Json(Arc::new(err)))
166 }
167}
168
169impl From<::std::string::FromUtf8Error> for Error {
170 fn from(err: ::std::string::FromUtf8Error) -> Error {
171 new_error(ErrorKind::Utf8(err))
172 }
173}
174
175impl From<ErrorKind> for Error {
176 fn from(kind: ErrorKind) -> Error {
177 new_error(kind)
178 }
179}
180
181impl From<signature::Error> for Error {
182 fn from(err: signature::Error) -> Error {
183 new_error(ErrorKind::Signing(err.to_string()))
184 }
185}
186
187#[cfg(test)]
188mod tests {
189 use wasm_bindgen_test::wasm_bindgen_test;
190
191 use super::*;
192
193 #[test]
194 #[wasm_bindgen_test]
195 fn test_error_rendering() {
196 assert_eq!(
197 "InvalidAlgorithmName",
198 Error::from(ErrorKind::InvalidAlgorithmName).to_string()
199 );
200 }
201}