Skip to main content

modkit_errors/
catalog.rs

1//! Error catalog support (`ErrDef` for use with `declare_errors`! macro)
2
3use crate::problem::Problem;
4use http::StatusCode;
5
6/// Static error definition from catalog
7#[derive(Debug, Clone, Copy)]
8pub struct ErrDef {
9    pub status: u16,
10    pub title: &'static str,
11    pub code: &'static str,
12    pub type_url: &'static str,
13}
14
15impl ErrDef {
16    /// Convert this error definition into a Problem with the given detail
17    #[inline]
18    pub fn as_problem(&self, detail: impl Into<String>) -> Problem {
19        // Convert u16 to StatusCode, using INTERNAL_SERVER_ERROR as fallback for invalid codes
20        let status = StatusCode::from_u16(self.status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
21        Problem::new(status, self.title, detail.into())
22            .with_code(self.code)
23            .with_type(self.type_url)
24    }
25}
26
27#[cfg(test)]
28#[cfg_attr(coverage_nightly, coverage(off))]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn err_def_to_problem_works() {
34        use http::StatusCode;
35
36        let def = ErrDef {
37            status: StatusCode::NOT_FOUND.as_u16(),
38            title: "Not Found",
39            code: "TEST_NOT_FOUND",
40            type_url: "https://errors.example.com/TEST_NOT_FOUND",
41        };
42
43        let problem = def.as_problem("Resource missing");
44        assert_eq!(problem.status, StatusCode::NOT_FOUND);
45        assert_eq!(problem.title, "Not Found");
46        assert_eq!(problem.detail, "Resource missing");
47        assert_eq!(problem.code, "TEST_NOT_FOUND");
48        assert_eq!(
49            problem.type_url,
50            "https://errors.example.com/TEST_NOT_FOUND"
51        );
52    }
53}