1use {
2 gcloud_gax::{grpc::Status, retry::TryAs},
3 gcloud_spanner::session::SessionError,
4 sea_orm::DbErr,
5 thiserror::Error,
6};
7
8#[derive(Debug)]
10pub enum SpannerTxError {
11 Grpc(Status),
12 Session(SessionError),
13 Db(DbErr),
14}
15
16impl From<Status> for SpannerTxError {
17 fn from(err: Status) -> Self {
18 SpannerTxError::Grpc(err)
19 }
20}
21
22impl From<SessionError> for SpannerTxError {
23 fn from(err: SessionError) -> Self {
24 SpannerTxError::Session(err)
25 }
26}
27
28impl From<DbErr> for SpannerTxError {
29 fn from(err: DbErr) -> Self {
30 SpannerTxError::Db(err)
31 }
32}
33
34impl TryAs<Status> for SpannerTxError {
35 fn try_as(&self) -> Option<&Status> {
36 match self {
37 SpannerTxError::Grpc(s) => Some(s),
38 _ => None,
39 }
40 }
41}
42
43impl std::fmt::Display for SpannerTxError {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 match self {
46 SpannerTxError::Grpc(e) => write!(f, "gRPC error: {}", e),
47 SpannerTxError::Session(e) => write!(f, "Session error: {}", e),
48 SpannerTxError::Db(e) => write!(f, "Database error: {}", e),
49 }
50 }
51}
52
53impl std::error::Error for SpannerTxError {}
54
55#[derive(Error, Debug)]
56pub enum SpannerDbErr {
57 #[error("Spanner connection error: {0}")]
58 Connection(String),
59
60 #[error("Spanner query error: {0}")]
61 Query(String),
62
63 #[error("Spanner execution error: {0}")]
64 Execution(String),
65
66 #[error("Transaction error: {0}")]
67 Transaction(String),
68
69 #[error("Row parse error: {0}")]
70 RowParse(String),
71
72 #[error("Type conversion error: column={column}, expected={expected}, got={got}")]
73 TypeConversion {
74 column: String,
75 expected: String,
76 got: String,
77 },
78
79 #[error("Column not found: {0}")]
80 ColumnNotFound(String),
81
82 #[error("Invalid configuration: {0}")]
83 InvalidConfig(String),
84}
85
86impl From<SpannerDbErr> for DbErr {
87 fn from(err: SpannerDbErr) -> Self {
88 match err {
89 SpannerDbErr::Connection(msg) => DbErr::Conn(sea_orm::RuntimeErr::Internal(msg)),
90 SpannerDbErr::Query(msg) => DbErr::Query(sea_orm::RuntimeErr::Internal(msg)),
91 SpannerDbErr::Execution(msg) => DbErr::Exec(sea_orm::RuntimeErr::Internal(msg)),
92 SpannerDbErr::Transaction(msg) => DbErr::Query(sea_orm::RuntimeErr::Internal(msg)),
93 SpannerDbErr::RowParse(msg) => DbErr::Type(msg),
94 SpannerDbErr::TypeConversion {
95 column,
96 expected,
97 got,
98 } => DbErr::Type(format!(
99 "column={}, expected={}, got={}",
100 column, expected, got
101 )),
102 SpannerDbErr::ColumnNotFound(col) => DbErr::Type(format!("column not found: {}", col)),
103 SpannerDbErr::InvalidConfig(msg) => DbErr::Conn(sea_orm::RuntimeErr::Internal(msg)),
104 }
105 }
106}
107
108impl From<gcloud_spanner::client::Error> for SpannerDbErr {
109 fn from(err: gcloud_spanner::client::Error) -> Self {
110 SpannerDbErr::Connection(err.to_string())
111 }
112}
113
114impl From<gcloud_spanner::row::Error> for SpannerDbErr {
115 fn from(err: gcloud_spanner::row::Error) -> Self {
116 SpannerDbErr::RowParse(err.to_string())
117 }
118}