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
use crate::;
use Fault;
use Serialize;
/// The type [Error] cannot directly be used as handlers or middlewares returned [Err] variant. A dedicated type is required.
/// The easiest implementation is to declare a [Newtype](https://doc.rust-lang.org/rust-by-example/generics/new_types.html),
/// derive it with the [HandlerErrorHelpers](crate::derive::HandlerErrorHelpers) and implement the [HandlerError] trait.
/// ```rust
/// # use actix_web::{App, HttpResponse, HttpServer, get};
/// # use explicit_error_http::{Fault, Error, HandlerError, derive::HandlerErrorHelpers};
/// # use log::{debug, error};
/// # use problem_details::ProblemDetails;
/// # use serde::Serialize;
/// #[derive(HandlerErrorHelpers)]
/// struct MyHandlerError(Error);
///
/// impl HandlerError for MyHandlerError {
/// // Used by the derive for conversion
/// fn from_error(value: Error) -> Self {
/// MyHandlerError(value)
/// }
///
/// // Set-up monitoring and your custom HTTP response body for faults
/// fn public_fault_response(fault: &Fault) -> impl Serialize {
/// #[cfg(debug_assertions)]
/// error!("{fault}");
///
/// #[cfg(not(debug_assertions))]
/// error!("{}", serde_json::json!(fault));
///
/// ProblemDetails::new()
/// .with_type(http::Uri::from_static("/errors/internal-server-error"))
/// .with_title("Internal server error")
/// }
///
/// fn error(&self) -> &Error {
/// &self.0
/// }
///
/// // Monitor domain variant of your errors and eventually override their body
/// fn domain_response(error: &explicit_error_http::DomainError) -> impl Serialize {
/// if error.output.http_status_code.as_u16() < 500 {
/// debug!("{error}");
/// } else {
/// error!("{error}");
/// }
/// error
/// }
/// }
///
/// #[get("/my-handler")]
/// async fn my_handler() -> Result<HttpResponse, MyHandlerError> {
/// Ok(HttpResponse::Ok().finish())
/// }
/// ```