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("backend: {0}")]
53 Backend(String),
54}
55
56impl ForgeError {
57 #[must_use]
59 pub fn status_code(&self) -> u16 {
60 match self {
61 ForgeError::NotFound(_) => 404,
62 ForgeError::BadRequest(_) | ForgeError::PathTraversal(_) => 400,
63 ForgeError::Unauthorised(_) => 401,
64 ForgeError::Forbidden(_) => 403,
65 ForgeError::Conflict(_) => 409,
66 ForgeError::Unsupported(_) => 501,
67 ForgeError::Git(g) => g.status_code(),
68 ForgeError::Io(_) | ForgeError::Serde(_) | ForgeError::Backend(_) => 500,
69 }
70 }
71
72 #[must_use]
74 pub fn to_response(&self) -> crate::ForgeResponse {
75 crate::ForgeResponse::error(self.status_code(), self.to_string())
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn status_mapping() {
85 assert_eq!(ForgeError::NotFound("x".into()).status_code(), 404);
86 assert_eq!(ForgeError::BadRequest("x".into()).status_code(), 400);
87 assert_eq!(ForgeError::PathTraversal("x".into()).status_code(), 400);
88 assert_eq!(ForgeError::Unauthorised("x".into()).status_code(), 401);
89 assert_eq!(ForgeError::Forbidden("x".into()).status_code(), 403);
90 assert_eq!(ForgeError::Conflict("x".into()).status_code(), 409);
91 assert_eq!(ForgeError::Unsupported("x".into()).status_code(), 501);
92 assert_eq!(ForgeError::Backend("x".into()).status_code(), 500);
93 }
94
95 #[test]
96 fn git_error_status_propagates() {
97 let g = solid_pod_rs_git::error::GitError::NotARepository("r".into());
98 let e = ForgeError::Git(g);
99 assert_eq!(e.status_code(), 404);
100 }
101}