1use crate::protocol::token::ServerError;
4use sqlx_core::error::{DatabaseError, ErrorKind};
5use sqlx_core::Error;
6
7#[derive(Debug)]
9pub struct MssqlDatabaseError(pub(crate) ServerError);
10
11impl MssqlDatabaseError {
12 pub fn number(&self) -> i32 {
14 self.0.number
15 }
16
17 pub fn state(&self) -> u8 {
19 self.0.state
20 }
21
22 pub fn class(&self) -> u8 {
24 self.0.class
25 }
26
27 pub fn message(&self) -> &str {
29 &self.0.message
30 }
31
32 pub fn server_name(&self) -> &str {
34 &self.0.server_name
35 }
36
37 pub fn procedure_name(&self) -> &str {
39 &self.0.procedure_name
40 }
41
42 pub fn line_number(&self) -> u32 {
44 self.0.line_number
45 }
46}
47
48impl std::fmt::Display for MssqlDatabaseError {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(
51 f,
52 "SQL Server error {} (state {}, class {}): {}",
53 self.0.number, self.0.state, self.0.class, self.0.message
54 )
55 }
56}
57
58impl std::error::Error for MssqlDatabaseError {}
59
60impl DatabaseError for MssqlDatabaseError {
61 fn message(&self) -> &str {
62 self.message()
63 }
64
65 fn as_error(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
66 self
67 }
68
69 fn as_error_mut(&mut self) -> &mut (dyn std::error::Error + Send + Sync + 'static) {
70 self
71 }
72
73 fn into_error(self: Box<Self>) -> Box<dyn std::error::Error + Send + Sync + 'static> {
74 self
75 }
76
77 fn kind(&self) -> ErrorKind {
78 ErrorKind::Other
79 }
80}
81
82pub(crate) fn server_error(error: ServerError) -> Error {
83 Error::database(MssqlDatabaseError(error))
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn server_error_returns_database_error() {
92 let error = server_error(ServerError {
93 number: 18456,
94 state: 1,
95 class: 14,
96 message: "Login failed".to_owned(),
97 server_name: "dbhost".to_owned(),
98 procedure_name: "login_proc".to_owned(),
99 line_number: 9,
100 });
101
102 let db_error = error.as_database_error().unwrap();
103 let mssql_error = db_error
104 .as_error()
105 .downcast_ref::<MssqlDatabaseError>()
106 .unwrap();
107
108 assert_eq!(18456, mssql_error.number());
109 assert_eq!(1, mssql_error.state());
110 assert_eq!(14, mssql_error.class());
111 assert_eq!("Login failed", mssql_error.message());
112 assert_eq!("dbhost", mssql_error.server_name());
113 assert_eq!("login_proc", mssql_error.procedure_name());
114 assert_eq!(9, mssql_error.line_number());
115 assert_eq!(None, db_error.code());
116 assert_eq!(ErrorKind::Other, db_error.kind());
117 }
118}