1#[derive(Debug, thiserror::Error)]
2pub enum FileError {
3 #[error("File too large: {size} bytes (max: {max} bytes)")]
4 TooLarge { size: usize, max: usize },
5
6 #[error("Invalid file type: {got} (allowed: {allowed:?})")]
7 InvalidType {
8 got: String,
9 allowed: Vec<String>,
10 },
11
12 #[error("MIME type mismatch: declared {declared}, detected {detected}")]
13 MimeMismatch { declared: String, detected: String },
14
15 #[error("Storage error: {message}")]
16 Storage {
17 message: String,
18 #[source]
19 source: Option<Box<dyn std::error::Error + Send + Sync>>,
20 },
21
22 #[error("Processing error: {message}")]
23 Processing { message: String },
24
25 #[error("File not found: {id}")]
26 NotFound { id: String },
27
28 #[error("Virus detected: {details}")]
29 VirusDetected { details: String },
30
31 #[error("Upload quota exceeded")]
32 QuotaExceeded,
33}
34
35impl FileError {
36 pub const fn error_code(&self) -> &'static str {
37 match self {
38 Self::TooLarge { .. } => "file_too_large",
39 Self::InvalidType { .. } => "file_invalid_type",
40 Self::MimeMismatch { .. } => "file_mime_mismatch",
41 Self::Storage { .. } => "file_storage_error",
42 Self::Processing { .. } => "file_processing_error",
43 Self::NotFound { .. } => "file_not_found",
44 Self::VirusDetected { .. } => "file_virus_detected",
45 Self::QuotaExceeded => "file_quota_exceeded",
46 }
47 }
48}