solid_pod_rs_forge/
error.rs1use thiserror::Error;
5
6#[derive(Debug, Error)]
8pub enum ForgeError {
9 #[error("not found: {0}")]
11 NotFound(String),
12
13 #[error("bad request: {0}")]
15 BadRequest(String),
16
17 #[error("invalid path: {0}")]
19 PathTraversal(String),
20
21 #[error("unauthorised: {0}")]
23 Unauthorised(String),
24
25 #[error("forbidden: {0}")]
27 Forbidden(String),
28
29 #[error("conflict: {0}")]
31 Conflict(String),
32
33 #[error("unsupported: {0}")]
36 Unsupported(String),
37
38 #[error("git: {0}")]
41 Git(#[from] solid_pod_rs_git::error::GitError),
42
43 #[error("i/o: {0}")]
45 Io(#[from] std::io::Error),
46
47 #[error("serialisation: {0}")]
49 Serde(#[from] serde_json::Error),
50
51 #[error("busy: {0}")]
53 Busy(String),
54
55 #[error("backend: {0}")]
57 Backend(String),
58}
59
60impl ForgeError {
61 #[must_use]
63 pub fn status_code(&self) -> u16 {
64 match self {
65 ForgeError::NotFound(_) => 404,
66 ForgeError::BadRequest(_) | ForgeError::PathTraversal(_) => 400,
67 ForgeError::Unauthorised(_) => 401,
68 ForgeError::Forbidden(_) => 403,
69 ForgeError::Conflict(_) => 409,
70 ForgeError::Unsupported(_) => 501,
71 ForgeError::Busy(_) => 503,
72 ForgeError::Git(g) => g.status_code(),
73 ForgeError::Io(_) | ForgeError::Serde(_) | ForgeError::Backend(_) => 500,
74 }
75 }
76
77 #[must_use]
79 pub fn to_response(&self) -> crate::ForgeResponse {
80 crate::ForgeResponse::error(self.status_code(), self.to_string())
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn status_mapping() {
90 assert_eq!(ForgeError::NotFound("x".into()).status_code(), 404);
91 assert_eq!(ForgeError::BadRequest("x".into()).status_code(), 400);
92 assert_eq!(ForgeError::PathTraversal("x".into()).status_code(), 400);
93 assert_eq!(ForgeError::Unauthorised("x".into()).status_code(), 401);
94 assert_eq!(ForgeError::Forbidden("x".into()).status_code(), 403);
95 assert_eq!(ForgeError::Conflict("x".into()).status_code(), 409);
96 assert_eq!(ForgeError::Unsupported("x".into()).status_code(), 501);
97 assert_eq!(ForgeError::Backend("x".into()).status_code(), 500);
98 }
99
100 #[test]
101 fn git_error_status_propagates() {
102 let g = solid_pod_rs_git::error::GitError::NotARepository("r".into());
103 let e = ForgeError::Git(g);
104 assert_eq!(e.status_code(), 404);
105 }
106}