webdav_server/error/
mod.rs1use std::num::TryFromIntError;
2use std::time::SystemTimeError;
3
4use axum::response::IntoResponse;
5use hyper::StatusCode;
6
7use crate::api;
8use crate::logger::{Entry, Level, Loggable, logging_enabled};
9use crate::storage;
10use crate::{model, wrap_internal_err};
11
12pub mod internal;
13
14#[derive(thiserror::Error, Debug)]
34pub enum Error {
35 #[error(transparent)]
37 StorageError(#[from] storage::Error),
38
39 #[error("API Error : {}", .0)]
41 ApiError(#[from] api::Error),
42
43 #[error("User Conflict")]
47 Conflict(String),
48
49 #[error("Database Error : {}", .0)]
52 DatabaseError(#[from] sqlx::Error),
53
54 #[error("Internal Error : {}", .0)]
56 InternalError(#[from] internal::Error),
57
58 #[error("Model Error : {}", .0)]
61 ModelError(#[from] model::Error),
62}
63
64wrap_internal_err! {
65 TryFromIntError, SystemTimeError => Error::InternalError
66}
67
68impl IntoResponse for Error {
69 fn into_response(self) -> axum::response::Response {
70 let telemetry = if logging_enabled() {
71 Some(Entry {
72 module: self.log_module(),
73 level: self.log_level(),
74 message: self.to_string(),
75 timestamp_ms: chrono::Utc::now().timestamp_millis(),
76 })
77 } else {
78 None
79 };
80
81 let mut response = match self {
82 StorageError(e) => e.into_response(),
85 ApiError(e) => e.into_response(),
86 ModelError(e) => e.into_response(),
87
88 Conflict(msg) => (StatusCode::CONFLICT, msg).into_response(),
90
91 DatabaseError(_) | InternalError(_) => {
93 (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error")
94 .into_response()
95 }
96 };
97
98 if let Some(t) = telemetry {
99 response.extensions_mut().insert(t);
100 }
101 response
102 }
103}
104
105use Error::{
106 ApiError, Conflict, DatabaseError, InternalError, ModelError, StorageError,
107};
108
109pub type Result<T> = core::result::Result<T, Error>;
110
111impl Loggable for Error {
112 fn log_level(&self) -> crate::logger::Level {
113 match self {
114 Self::StorageError(e) => e.log_level(),
115 Self::ApiError(e) => e.log_level(),
116 Self::Conflict(_) => Level::Warning,
117 Self::ModelError(e) => e.log_level(),
118 Self::DatabaseError(_) | Self::InternalError(_) => Level::Error,
119 }
120 }
121
122 #[inline]
123 fn log_module(&self) -> crate::logger::Module {
124 match self {
125 Self::StorageError(e) => e.log_module(),
126 Self::ApiError(e) => e.log_module(),
127 Self::ModelError(e) => e.log_module(),
128 _ => crate::logger::Module::Server,
129 }
130 }
131}