nuclear/
error.rs

1pub use anyhow::{Error, Result};
2
3use crate::http::{Body, StatusCode};
4use crate::response::Response;
5
6pub trait CatchExt {
7    type Value;
8    type Error;
9    fn catch<E>(self) -> Result<Result<Self::Value, E>, Self::Error>
10    where
11        E: std::error::Error + Send + Sync + 'static;
12}
13
14impl<T> CatchExt for Result<T> {
15    type Value = T;
16    type Error = Error;
17
18    fn catch<E>(self) -> Result<Result<Self::Value, E>, Self::Error>
19    where
20        E: std::error::Error + Send + Sync + 'static,
21    {
22        match self {
23            Ok(value) => Ok(Ok(value)),
24            Err(err) => match err.downcast::<E>() {
25                Ok(e) => Ok(Err(e)),
26                Err(err) => Err(err),
27            },
28        }
29    }
30}
31
32#[derive(Debug, thiserror::Error)]
33#[error("StatusError: {}", .status.as_str())]
34pub struct StatusError {
35    pub status: StatusCode,
36}
37
38impl StatusError {
39    pub const NOT_FOUND: Self = Self {
40        status: StatusCode::NOT_FOUND,
41    };
42
43    pub fn new(status: StatusCode) -> Self {
44        Self { status }
45    }
46}
47
48impl From<StatusError> for Response {
49    fn from(e: StatusError) -> Self {
50        let body = match e.status.canonical_reason() {
51            Some(s) => s.into(),
52            None => Body::empty(),
53        };
54        Response::new(e.status, body)
55    }
56}