1use axum::{
2 http::StatusCode,
3 response::{IntoResponse, Response},
4};
5use edda_types::{monster::MonsterError, rules_text::RulesTextError};
6
7#[derive(Debug, thiserror::Error)]
9pub enum ApiError {
10 #[error("not found")]
11 NotFound,
12 #[error("the shared library can't be changed here; make a copy for the campaign instead")]
14 Shared,
15 #[error("{0}")]
17 Limit(String),
18 #[error("only a DM device can change the campaign's monsters, spells and conditions")]
21 DmOnly,
22 #[error("{0}")]
24 BadRequest(String),
25 #[error("{0}")]
27 Conflict(String),
28 #[error(transparent)]
29 Invalid(#[from] MonsterError),
30 #[error(transparent)]
31 InvalidText(#[from] RulesTextError),
32 #[error("database error: {0}")]
33 Database(#[from] sqlx::Error),
34 #[error("corrupt stored data: {0}")]
35 Corrupt(String),
36}
37
38impl IntoResponse for ApiError {
39 fn into_response(self) -> Response {
40 let status = match &self {
41 ApiError::NotFound => StatusCode::NOT_FOUND,
42 ApiError::BadRequest(_) => StatusCode::BAD_REQUEST,
43 ApiError::Conflict(_) => StatusCode::CONFLICT,
44 ApiError::Shared | ApiError::DmOnly | ApiError::Limit(_) => StatusCode::FORBIDDEN,
45 ApiError::Invalid(_) | ApiError::InvalidText(_) => StatusCode::UNPROCESSABLE_ENTITY,
46 ApiError::Database(_) | ApiError::Corrupt(_) => StatusCode::INTERNAL_SERVER_ERROR,
47 };
48 edda_server::error_response(status, &self)
49 }
50}