modkit_odata/
problem_mapping.rs1use crate::Error;
8use crate::errors::ErrorCode;
9use modkit_errors::problem::Problem;
10
11impl From<Error> for Problem {
12 fn from(err: Error) -> Self {
13 use Error::{
14 CursorInvalidBase64, CursorInvalidDirection, CursorInvalidFields, CursorInvalidJson,
15 CursorInvalidKeys, CursorInvalidVersion, Db, FilterMismatch, InvalidCursor,
16 InvalidFilter, InvalidLimit, InvalidOrderByField, OrderMismatch, OrderWithCursor,
17 ParsingUnavailable,
18 };
19
20 match err {
21 InvalidFilter(msg) => ErrorCode::odata_errors_invalid_filter_v1()
23 .as_problem(format!("Invalid $filter: {msg}")),
24
25 InvalidOrderByField(field) => ErrorCode::odata_errors_invalid_orderby_v1()
27 .as_problem(format!("Unsupported $orderby field: {field}")),
28
29 InvalidCursor
31 | CursorInvalidBase64
32 | CursorInvalidJson
33 | CursorInvalidVersion
34 | CursorInvalidKeys
35 | CursorInvalidFields
36 | CursorInvalidDirection => {
37 ErrorCode::odata_errors_invalid_cursor_v1().as_problem(err.to_string())
38 }
39
40 OrderMismatch => ErrorCode::odata_errors_invalid_orderby_v1()
42 .as_problem("Order mismatch between cursor and query"),
43
44 FilterMismatch => ErrorCode::odata_errors_invalid_filter_v1()
45 .as_problem("Filter mismatch between cursor and query"),
46
47 InvalidLimit => {
48 ErrorCode::odata_errors_invalid_filter_v1().as_problem("Invalid limit parameter")
49 }
50
51 OrderWithCursor => ErrorCode::odata_errors_invalid_cursor_v1()
52 .as_problem("Cannot specify both $orderby and cursor parameters"),
53
54 Db(_msg) => {
56 ErrorCode::odata_errors_internal_v1()
58 .as_problem("An internal error occurred while processing the OData query")
59 }
60
61 ParsingUnavailable(msg) => ErrorCode::odata_errors_internal_v1()
63 .as_problem(format!("OData parsing unavailable: {msg}")),
64 }
65 }
66}
67
68#[cfg(test)]
69#[cfg_attr(coverage_nightly, coverage(off))]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_filter_error_converts_to_problem() {
75 use http::StatusCode;
76
77 let err = Error::InvalidFilter("malformed".to_owned());
78 let problem: Problem = err.into();
79
80 assert_eq!(problem.status, StatusCode::UNPROCESSABLE_ENTITY);
81 assert_eq!(problem.title, "Invalid Filter");
82 assert!(problem.detail.contains("malformed"));
83 assert!(problem.code.contains("odata"));
84 assert!(problem.code.contains("invalid_filter"));
85 }
86
87 #[test]
88 fn test_orderby_error_converts_to_problem() {
89 use http::StatusCode;
90
91 let err = Error::InvalidOrderByField("unknown".to_owned());
92 let problem: Problem = err.into();
93
94 assert_eq!(problem.status, StatusCode::UNPROCESSABLE_ENTITY);
95 assert_eq!(problem.title, "Invalid OrderBy");
96 assert!(problem.code.contains("odata"));
97 assert!(problem.code.contains("invalid_orderby"));
98 }
99
100 #[test]
101 fn test_cursor_error_converts_to_problem() {
102 use http::StatusCode;
103
104 let err = Error::CursorInvalidBase64;
105 let problem: Problem = err.into();
106
107 assert_eq!(problem.status, StatusCode::UNPROCESSABLE_ENTITY);
108 assert_eq!(problem.title, "Invalid Cursor");
109 assert!(problem.code.contains("odata"));
110 assert!(problem.code.contains("invalid_cursor"));
111 }
112}