1use std::fmt;
8
9pub type FhirPathResult<T> = Result<T, FhirPathError>;
11
12#[derive(Debug)]
14pub enum FhirPathError {
15 ParseError(String),
17
18 EvaluationError(String),
20
21 IoError(std::io::Error),
23
24 JsonError(serde_json::Error),
26
27 InvalidInput(String),
29
30 NotFound(String),
32
33 NotImplemented(String),
35
36 ConfigError(String),
38
39 HttpError(u16, String),
41
42 NetworkError(String),
44
45 TerminologyError(String),
47}
48
49impl fmt::Display for FhirPathError {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 FhirPathError::ParseError(msg) => write!(f, "Parse error: {}", msg),
53 FhirPathError::EvaluationError(msg) => write!(f, "Evaluation error: {}", msg),
54 FhirPathError::IoError(err) => write!(f, "IO error: {}", err),
55 FhirPathError::JsonError(err) => write!(f, "JSON error: {}", err),
56 FhirPathError::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
57 FhirPathError::NotFound(msg) => write!(f, "Not found: {}", msg),
58 FhirPathError::NotImplemented(msg) => write!(f, "Not implemented: {}", msg),
59 FhirPathError::ConfigError(msg) => write!(f, "Configuration error: {}", msg),
60 FhirPathError::HttpError(code, msg) => write!(f, "HTTP {} error: {}", code, msg),
61 FhirPathError::NetworkError(msg) => write!(f, "Network error: {}", msg),
62 FhirPathError::TerminologyError(msg) => write!(f, "Terminology error: {}", msg),
63 }
64 }
65}
66
67impl std::error::Error for FhirPathError {}
68
69impl From<std::io::Error> for FhirPathError {
70 fn from(err: std::io::Error) -> Self {
71 FhirPathError::IoError(err)
72 }
73}
74
75impl From<serde_json::Error> for FhirPathError {
76 fn from(err: serde_json::Error) -> Self {
77 FhirPathError::JsonError(err)
78 }
79}
80
81impl From<String> for FhirPathError {
82 fn from(err: String) -> Self {
83 FhirPathError::InvalidInput(err)
84 }
85}
86
87impl axum::response::IntoResponse for FhirPathError {
88 fn into_response(self) -> axum::response::Response {
89 self.into()
90 }
91}
92
93impl From<FhirPathError> for axum::response::Response {
94 fn from(err: FhirPathError) -> Self {
95 use axum::Json;
96 use axum::http::StatusCode;
97 use axum::response::IntoResponse;
98
99 let (status, message) = match err {
100 FhirPathError::ParseError(msg) => (StatusCode::BAD_REQUEST, msg),
101 FhirPathError::EvaluationError(msg) => (StatusCode::UNPROCESSABLE_ENTITY, msg),
102 FhirPathError::InvalidInput(msg) => (StatusCode::BAD_REQUEST, msg),
103 FhirPathError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
104 FhirPathError::NotImplemented(msg) => (StatusCode::NOT_IMPLEMENTED, msg),
105 FhirPathError::ConfigError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
106 FhirPathError::HttpError(code, msg) => (
107 StatusCode::from_u16(code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
108 msg,
109 ),
110 FhirPathError::NetworkError(msg) => (StatusCode::BAD_GATEWAY, msg),
111 FhirPathError::TerminologyError(msg) => (StatusCode::BAD_GATEWAY, msg),
112 _ => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()),
113 };
114
115 let operation_outcome = serde_json::json!({
117 "resourceType": "OperationOutcome",
118 "issue": [{
119 "severity": "error",
120 "code": match status {
121 StatusCode::BAD_REQUEST => "invalid",
122 StatusCode::NOT_FOUND => "not-found",
123 StatusCode::UNPROCESSABLE_ENTITY => "processing",
124 StatusCode::NOT_IMPLEMENTED => "not-supported",
125 _ => "exception",
126 },
127 "diagnostics": message
128 }]
129 });
130
131 (status, Json(operation_outcome)).into_response()
132 }
133}