|
1 | 1 | // Error handling based on the failure crate |
2 | 2 |
|
| 3 | +use std::error::Error; |
3 | 4 | use std::fmt; |
4 | 5 | use std::result; |
5 | 6 |
|
6 | | -use failure::{Backtrace, Context, Error, Fail}; |
| 7 | +use backtrace::Backtrace; |
| 8 | +use thiserror::Error; |
7 | 9 |
|
8 | | -pub type VapidResult<T> = result::Result<T, Error>; |
| 10 | +pub type VapidResult<T> = result::Result<T, VapidError>; |
9 | 11 |
|
10 | 12 | #[derive(Debug)] |
11 | 13 | pub struct VapidError { |
12 | | - inner: Context<VapidErrorKind>, |
| 14 | + kind: VapidErrorKind, |
| 15 | + pub backtrace: Backtrace, |
13 | 16 | } |
14 | 17 |
|
15 | | -#[derive(Clone, Eq, PartialEq, Debug, Fail)] |
| 18 | +#[derive(Debug, Error)] |
16 | 19 | pub enum VapidErrorKind { |
17 | | - #[fail(display = "Invalid public key")] |
| 20 | + /// General IO instance. Can be returned for bad files or key data. |
| 21 | + #[error("IO error: {:?}", .0)] |
| 22 | + File(#[from] std::io::Error), |
| 23 | + /// OpenSSL errors. These tend not to be very specific (or helpful). |
| 24 | + #[error("OpenSSL error: {:?}", .0)] |
| 25 | + OpenSSL(#[from] openssl::error::ErrorStack), |
| 26 | + /// JSON parsing error. |
| 27 | + #[error("JSON error:{:?}", .0)] |
| 28 | + Json(#[from] serde_json::Error), |
| 29 | + |
| 30 | + /// An invalid public key was specified. Is it EC Prime256v1? |
| 31 | + #[error("Invalid public key")] |
18 | 32 | PublicKey, |
19 | | - #[fail(display = "VAPID error: {}", _0)] |
| 33 | + /// A vapid error occurred. |
| 34 | + #[error("VAPID error: {}", .0)] |
20 | 35 | Protocol(String), |
21 | | - #[fail(display = "Internal Error {:?}", _0)] |
| 36 | + /// A random internal error |
| 37 | + #[error("Internal Error {:?}", .0)] |
22 | 38 | Internal(String), |
23 | 39 | } |
24 | 40 |
|
25 | | -impl Fail for VapidError { |
26 | | - fn cause(&self) -> Option<&dyn Fail> { |
27 | | - self.inner.cause() |
28 | | - } |
29 | | - |
30 | | - fn backtrace(&self) -> Option<&Backtrace> { |
31 | | - self.inner.backtrace() |
| 41 | +/// VapidErrors are the general error wrapper that we use. These include |
| 42 | +/// a public `backtrace` which can be combined with your own because they're |
| 43 | +/// stupidly useful. |
| 44 | +impl VapidError { |
| 45 | + pub fn kind(&self) -> &VapidErrorKind { |
| 46 | + &self.kind |
32 | 47 | } |
33 | | -} |
34 | 48 |
|
35 | | -impl fmt::Display for VapidError { |
36 | | - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
37 | | - fmt::Display::fmt(&self.inner, f) |
| 49 | + pub fn internal(msg: &str) -> Self { |
| 50 | + VapidErrorKind::Internal(msg.to_owned()).into() |
38 | 51 | } |
39 | 52 | } |
40 | 53 |
|
41 | | -impl From<VapidErrorKind> for VapidError { |
42 | | - fn from(kind: VapidErrorKind) -> VapidError { |
43 | | - Context::new(kind).into() |
| 54 | +impl<T> From<T> for VapidError |
| 55 | +where |
| 56 | + VapidErrorKind: From<T>, |
| 57 | +{ |
| 58 | + fn from(item: T) -> Self { |
| 59 | + VapidError { |
| 60 | + kind: VapidErrorKind::from(item), |
| 61 | + backtrace: Backtrace::new(), |
| 62 | + } |
44 | 63 | } |
45 | 64 | } |
46 | 65 |
|
47 | | -impl From<Context<VapidErrorKind>> for VapidError { |
48 | | - fn from(inner: Context<VapidErrorKind>) -> VapidError { |
49 | | - VapidError { inner } |
| 66 | +impl Error for VapidError { |
| 67 | + fn source(&self) -> Option<&(dyn Error + 'static)> { |
| 68 | + self.kind.source() |
50 | 69 | } |
51 | 70 | } |
52 | 71 |
|
53 | | -impl From<Error> for VapidError { |
54 | | - fn from(err: Error) -> VapidError { |
55 | | - VapidErrorKind::Internal(format!("Error: {:?}", err)).into() |
| 72 | +impl fmt::Display for VapidError { |
| 73 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 74 | + self.kind.fmt(f) |
56 | 75 | } |
57 | 76 | } |
0 commit comments