1use std::{collections::BTreeSet, sync::Arc};
2
3use http::StatusCode;
4use predawn::{
5 error_ext::{ErrorExt, NextError},
6 location::Location,
7 response_error::ResponseError,
8};
9use sea_orm::DbErr;
10use snafu::Snafu;
11
12use crate::Transaction;
13
14#[derive(Debug, Snafu)]
15#[snafu(visibility(pub(crate)))]
16pub enum Error {
17 #[snafu(display("{source}"))]
18 DbErr {
19 #[snafu(implicit)]
20 location: Location,
21 source: DbErr,
22 },
23
24 #[snafu(display("not found a data source `{name}`"))]
25 NotFoundDataSource {
26 #[snafu(implicit)]
27 location: Location,
28 name: Box<str>,
29 },
30
31 #[snafu(display("not set data sources in the current context"))]
32 NotSetDataSources {
33 #[snafu(implicit)]
34 location: Location,
35 },
36
37 #[snafu(display("inconsistent data source and transaction, data source name: `{data_source_name}`, transaction name : `{transaction_name}`"))]
38 InconsistentDataSourceAndTransaction {
39 #[snafu(implicit)]
40 location: Location,
41 data_source_name: Arc<str>,
42 transaction_name: Arc<str>,
43 txn: Transaction,
44 },
45
46 #[snafu(display("transaction have more than one reference, data source name: `{data_source_name}`, transaction hierarchy: `{transaction_hierarchy}`"))]
47 TransactionHaveMoreThanOneReference {
48 #[snafu(implicit)]
49 location: Location,
50 data_source_name: Arc<str>,
51 transaction_hierarchy: usize,
52 txn: Transaction,
53 },
54
55 #[snafu(display("nested transaction have more than one reference, data source name: `{data_source_name}`, current transaction hierarchy: `{current_transaction_hierarchy}`, nested transaction hierarchy: `{nested_transaction_hierarchy}`"))]
56 NestedTransactionHaveMoreThanOneReference {
57 #[snafu(implicit)]
58 location: Location,
59 data_source_name: Arc<str>,
60 current_transaction_hierarchy: usize,
61 nested_transaction_hierarchy: usize,
62 txn: Transaction,
63 },
64}
65
66impl ErrorExt for Error {
67 fn entry(&self) -> (Location, NextError<'_>) {
68 match self {
69 Error::DbErr { location, source } => (*location, NextError::Std(source)),
70
71 Error::NotFoundDataSource { location, .. }
72 | Error::NotSetDataSources { location }
73 | Error::InconsistentDataSourceAndTransaction { location, .. }
74 | Error::TransactionHaveMoreThanOneReference { location, .. }
75 | Error::NestedTransactionHaveMoreThanOneReference { location, .. } => {
76 (*location, NextError::None)
77 }
78 }
79 }
80}
81
82impl ResponseError for Error {
83 fn as_status(&self) -> StatusCode {
84 StatusCode::INTERNAL_SERVER_ERROR
85 }
86
87 fn status_codes(codes: &mut BTreeSet<StatusCode>) {
88 codes.insert(StatusCode::INTERNAL_SERVER_ERROR);
89 }
90}