webdav_server/storage/
error.rs1use std::{num::TryFromIntError, path::PathBuf, time::SystemTimeError};
2
3use axum::response::IntoResponse;
4use hyper::StatusCode;
5use tokio::io;
6
7use crate::{
8 error::internal,
9 logger::{self, Loggable},
10 storage, wrap_internal_err,
11};
12
13#[derive(thiserror::Error, Debug)]
19pub enum Error {
20 #[error("Root storage doesn't exist")]
24 VaultNotFound,
25
26 #[error("Invalid File Name")]
29 InvalidFileName,
30
31 #[error("File Already Exists : {}", .0)]
34 FileAlreadyExists(String),
35
36 #[error("Couldn't create temporary file at {path}")]
38 CreateTempFile {
39 path: PathBuf,
40 #[source]
41 source: io::Error,
42 },
43
44 #[error("Writing chunk to disk failed, file : {path}")]
46 WriteChunkFailure {
47 path: PathBuf,
48 #[source]
49 source: io::Error,
50 },
51
52 #[error("Couldn't gather next chunk of data : {}", .0)]
54 StreamReadError(#[from] io::Error),
55
56 #[error("Failed to rename file : {path}")]
58 RenameError {
59 path: PathBuf,
60 #[source]
61 source: io::Error,
62 },
63
64 #[error("Invalid Path : {path}")]
66 InvalidPath { path: PathBuf },
67
68 #[error("Internal Error : {}", .0)]
70 Internal(#[from] internal::Error),
71
72 #[error("Blob Not found")]
74 NotFound,
75}
76
77pub type Result<T> = core::result::Result<T, storage::Error>;
78
79wrap_internal_err! { TryFromIntError, SystemTimeError => Error::Internal }
80
81impl IntoResponse for Error {
82 fn into_response(self) -> axum::response::Response {
83 use Error::{
84 CreateTempFile, FileAlreadyExists, Internal, InvalidFileName,
85 InvalidPath, NotFound, RenameError, StreamReadError, VaultNotFound,
86 WriteChunkFailure,
87 };
88
89 match self {
90 InvalidFileName | InvalidPath { .. } => {
92 (StatusCode::BAD_REQUEST, "Invalid file path or name".into())
93 }
94 FileAlreadyExists(msg) => (StatusCode::CONFLICT, msg),
95 NotFound => (StatusCode::NOT_FOUND, "Blob not found".into()),
96
97 VaultNotFound
99 | CreateTempFile { .. }
100 | WriteChunkFailure { .. }
101 | StreamReadError(_)
102 | RenameError { .. }
103 | Internal(_) => (
104 StatusCode::INTERNAL_SERVER_ERROR,
105 "Internal Server Error".into(),
106 ),
107 }
108 .into_response()
109 }
110}
111
112impl Loggable for Error {
113 fn log_level(&self) -> crate::logger::Level {
114 use logger::Level;
115 match self {
116 Self::VaultNotFound => Level::Fatal,
117 _ => Level::Error,
118 }
119 }
120
121 fn log_module(&self) -> logger::Module {
122 logger::Module::Storage
123 }
124}