-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.rs
162 lines (154 loc) · 4.79 KB
/
error.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
use std::fmt;
use axum::response::IntoResponse;
use axum::Json;
use gluer::metadata;
use hyper::StatusCode;
use serde::Serialize;
use tracing::error;
/// The api compatible error type.
/// On the frontend there are specific error messages displayed for each of the error types.
///
/// More specific error messages are removed to be api compatible.
/// Those messages are logged however.
#[metadata]
#[repr(i64)]
#[derive(Debug, Clone, Copy, Serialize)]
pub enum Error {
/// The user provided arguments are malformed
Arguments,
/// A file could not be found or opened
FileOpen,
/// Could not connect to server
Network,
/// Invalid file format
InvalidFormat,
/// No matching results
NothingFound,
/// Deletion not possible as the user is still referenced
ReferencedUser,
/// Deletion not possible as the category is still referenced
ReferencedCategory,
/// The book has invalid or missing fields
InvalidBook,
/// The user has invalid or missing fields
InvalidUser,
/// User may not borrow
LendingUserMayNotBorrow,
/// Book cannot be borrowed
LendingBookNotBorrowable,
/// Book is already borrowed
LendingBookAlreadyBorrowed,
/// Book cannot be reserved as the user already borrows it
LendingBookAlreadyBorrowedByUser,
/// The book cannot be reserved or returned as it is not borrowed
LendingBookNotBorrowed,
/// The book is already reserved
LendingBookAlreadyReserved,
/// The book is not reserved
LendingBookNotReserved,
/// The database version is too old
UnsupportedProjectVersion,
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
#[cfg(feature = "sqlite")]
#[allow(deprecated)]
impl From<rusqlite::Error> for Error {
fn from(e: rusqlite::Error) -> Self {
match e {
rusqlite::Error::QueryReturnedNoRows => Self::NothingFound,
_ => {
error!("SQL: {e}");
Self::InvalidFormat
}
}
}
}
impl From<std::convert::Infallible> for Error {
fn from(e: std::convert::Infallible) -> Self {
error!("convert::Infallible: {e:?}");
Self::Arguments
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
use std::io::ErrorKind;
error!("File Error: {e}");
match e.kind() {
ErrorKind::ConnectionRefused
| ErrorKind::ConnectionReset
| ErrorKind::ConnectionAborted
| ErrorKind::NotConnected
| ErrorKind::AddrInUse
| ErrorKind::AddrNotAvailable => Self::Network,
_ => Self::FileOpen,
}
}
}
impl From<roxmltree::Error> for Error {
fn from(e: roxmltree::Error) -> Self {
error!("Invalid XML Format: {e:?}");
Self::InvalidFormat
}
}
impl From<csv::Error> for Error {
fn from(e: csv::Error) -> Self {
match e.into_kind() {
csv::ErrorKind::Io(e) => Self::from(e),
e => {
error!("Invalid CSV Format: {e:?}");
Self::InvalidFormat
}
}
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
error!("Invalid JSON Format: {e:?}");
Self::InvalidFormat
}
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Self {
error!("Network request: {e:?}");
Self::Network
}
}
impl<ER: std::error::Error + 'static, T: oauth2::ErrorResponse + 'static>
From<oauth2::RequestTokenError<ER, T>> for Error
{
fn from(e: oauth2::RequestTokenError<ER, T>) -> Self {
error!("OAUTH Failed: {e:?}");
Self::Network
}
}
impl IntoResponse for Error {
fn into_response(self) -> axum::response::Response {
let status = match self {
Error::Arguments
| Error::InvalidFormat
| Error::ReferencedUser
| Error::ReferencedCategory
| Error::InvalidBook
| Error::InvalidUser
| Error::LendingUserMayNotBorrow
| Error::LendingBookNotBorrowable
| Error::LendingBookAlreadyBorrowed
| Error::LendingBookAlreadyBorrowedByUser
| Error::LendingBookNotBorrowed
| Error::LendingBookAlreadyReserved
| Error::LendingBookNotReserved => StatusCode::BAD_REQUEST,
Error::FileOpen | Error::NothingFound => StatusCode::NOT_FOUND,
Error::UnsupportedProjectVersion => StatusCode::INTERNAL_SERVER_ERROR,
Error::Network => StatusCode::SERVICE_UNAVAILABLE,
};
(status, Json(self)).into_response()
}
}
/// Result type using the api error.
#[metadata]
pub type Result<T> = std::result::Result<T, Error>;