1use dioxus::{
2 fullstack::AsStatusCode,
3 prelude::{ServerFnError, StatusCode},
4};
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8#[derive(Debug, Serialize, Deserialize, Error)]
10pub enum ApiError {
11 #[error("bad request: {0}")]
13 BadRequest(String),
14
15 #[error("forbidden: {0}")]
17 Forbidden(String),
18
19 #[error("not found")]
21 NotFound,
22
23 #[error("domain error: {0}")]
25 Domain(String),
26
27 #[cfg(not(debug_assertions))]
29 #[error("An unexpected error occurred")]
30 Unexpected,
31
32 #[cfg(debug_assertions)]
34 #[error("An unexpected error occurred {message}")]
35 Unexpected {
36 message: String,
38 },
39}
40
41impl AsStatusCode for ApiError {
42 fn as_status_code(&self) -> StatusCode {
43 match self {
44 ApiError::BadRequest(_) => StatusCode::FORBIDDEN,
45 ApiError::Forbidden(_) => StatusCode::FORBIDDEN,
46 ApiError::NotFound => StatusCode::NOT_FOUND,
47 ApiError::Domain(_) => StatusCode::BAD_REQUEST,
48 #[cfg(not(debug_assertions))]
49 ApiError::Unexpected => StatusCode::INTERNAL_SERVER_ERROR,
50 #[cfg(debug_assertions)]
51 ApiError::Unexpected { .. } => StatusCode::INTERNAL_SERVER_ERROR,
52 }
53 }
54}
55
56#[cfg(not(debug_assertions))]
57impl From<ServerFnError> for ApiError {
58 fn from(_value: ServerFnError) -> Self {
59 ApiError::Unexpected
60 }
61}
62
63#[cfg(debug_assertions)]
64impl From<ServerFnError> for ApiError {
65 fn from(value: ServerFnError) -> Self {
66 ApiError::Unexpected {
67 message: value.to_string(),
68 }
69 }
70}
71
72#[cfg(feature = "server")]
73mod server_only {
74 use dioxus::prelude::*;
75 use server::error::ServerError;
76
77 use super::*;
78
79 impl From<ServerError> for ApiError {
80 fn from(err: ServerError) -> Self {
81 match err {
82 ServerError::Forbidden(msg) => ApiError::Forbidden(msg),
83 ServerError::NotFound => ApiError::NotFound,
84 ServerError::Domain(e) => ApiError::Domain(e.to_string()),
85 ServerError::Internal(e) => {
86 error!("Internal server error: {e:#}");
87 #[cfg(debug_assertions)]
88 {
89 ApiError::Unexpected {
90 message: e.to_string(),
91 }
92 }
93 #[cfg(not(debug_assertions))]
94 {
95 ApiError::Unexpected
96 }
97 }
98 }
99 }
100 }
101}