trino_rust_client/models/
error.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Deserialize, Serialize)]
6#[serde(rename_all = "camelCase")]
7pub struct QueryError {
8 pub message: String,
9 pub sql_state: Option<String>,
10 pub error_code: i32,
11 pub error_name: String,
12 pub error_type: String,
13 pub error_location: Option<ErrorLocation>,
14 #[serde(default)]
15 pub failure_info: Option<FailureInfo>,
16}
17
18#[non_exhaustive]
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum TrinoErrorKind {
27 SyntaxError,
28 PermissionDenied,
29 UserCanceled,
30 CatalogNotFound,
31 SchemaNotFound,
32 SchemaAlreadyExists,
33 TableNotFound,
34 TableAlreadyExists,
35 ColumnNotFound,
36 ColumnAlreadyExists,
37 FunctionNotFound,
38 NotSupported,
39 Other,
41}
42
43impl TrinoErrorKind {
44 fn from_name(error_name: &str) -> Self {
45 match error_name {
46 "SYNTAX_ERROR" => Self::SyntaxError,
47 "PERMISSION_DENIED" => Self::PermissionDenied,
48 "USER_CANCELED" => Self::UserCanceled,
49 "CATALOG_NOT_FOUND" => Self::CatalogNotFound,
50 "SCHEMA_NOT_FOUND" => Self::SchemaNotFound,
51 "SCHEMA_ALREADY_EXISTS" => Self::SchemaAlreadyExists,
52 "TABLE_NOT_FOUND" => Self::TableNotFound,
53 "TABLE_ALREADY_EXISTS" => Self::TableAlreadyExists,
54 "COLUMN_NOT_FOUND" => Self::ColumnNotFound,
55 "COLUMN_ALREADY_EXISTS" => Self::ColumnAlreadyExists,
56 "FUNCTION_NOT_FOUND" => Self::FunctionNotFound,
57 "NOT_SUPPORTED" => Self::NotSupported,
58 _ => Self::Other,
59 }
60 }
61}
62
63impl QueryError {
64 pub fn kind(&self) -> TrinoErrorKind {
78 TrinoErrorKind::from_name(&self.error_name)
79 }
80}
81
82#[derive(Debug, Deserialize, Serialize)]
83#[serde(rename_all = "camelCase")]
84pub struct ErrorLocation {
85 pub line_number: u32,
86 pub column_number: u32,
87}
88
89#[derive(Debug, Deserialize, Serialize)]
90#[serde(rename_all = "camelCase")]
91pub struct FailureInfo {
92 #[serde(rename = "type")]
93 pub ty: String,
94 pub suppressed: Vec<FailureInfo>,
95 pub stack: Vec<String>,
96 pub message: Option<String>,
97 pub cause: Option<Box<FailureInfo>>,
98 pub error_location: Option<ErrorLocation>,
99}
100
101impl fmt::Display for QueryError {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 writeln!(f, "message: {}", self.message)?;
104 if let Some(st) = &self.sql_state {
105 writeln!(f, "sql_state: {}", st)?;
106 }
107 writeln!(f, "error_code: {}", self.error_code)?;
108 writeln!(f, "error_type: {}", self.error_name)?;
109 if let Some(loc) = &self.error_location {
110 writeln!(f, "error_location: {}", loc)?;
111 }
112 if let Some(fi) = &self.failure_info {
113 writeln!(f, "failure_info: {}", fi)?;
114 }
115 Ok(())
116 }
117}
118
119impl std::error::Error for QueryError {}
120
121impl fmt::Display for ErrorLocation {
122 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123 write!(f, "({}, {})", self.line_number, self.column_number)
124 }
125}
126
127impl fmt::Display for FailureInfo {
128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 writeln!(f, "ty: {}", self.ty)?;
130 if let Some(msg) = &self.message {
131 writeln!(f, "message: {}", msg)?;
132 }
133 if let Some(loc) = &self.error_location {
134 writeln!(f, "loc: {}", loc)?;
135 }
136 writeln!(f, "stack:")?;
137 for s in &self.stack {
138 writeln!(f, "\ttype: {}", s)?;
139 }
140 if let Some(cause) = &self.cause {
141 writeln!(f, "cause: {}", cause)?;
142 }
143 Ok(())
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150
151 #[test]
152 fn test_loc() {
153 let loc = ErrorLocation {
154 line_number: 100,
155 column_number: 15,
156 };
157
158 assert_eq!("(100, 15)", format!("{}", loc));
159 }
160
161 #[test]
162 fn test_failure() {
163 let failure = FailureInfo {
164 ty: "xxxty".into(),
165 suppressed: vec![],
166 stack: vec!["stack_1".into(), "stack_2".into(), "stack_3".into()],
167 message: None,
168 cause: None,
169 error_location: None,
170 };
171
172 println!("{}", failure);
173 }
174
175 #[test]
176 fn test_error_kind() {
177 let mut err = QueryError {
178 message: "boom".into(),
179 sql_state: None,
180 error_code: 44,
181 error_name: "TABLE_NOT_FOUND".into(),
182 error_type: "USER_ERROR".into(),
183 error_location: None,
184 failure_info: None,
185 };
186 assert_eq!(err.kind(), TrinoErrorKind::TableNotFound);
187
188 err.error_name = "SOME_FUTURE_TRINO_ERROR".into();
189 assert_eq!(err.kind(), TrinoErrorKind::Other);
190 }
191}