tosic_http/error/
response_error.rs1use crate::body::BoxBody;
4use crate::error::macros::{downcast_dyn, downcast_get_type_id};
5use crate::response::HttpResponse;
6use bytes::BytesMut;
7use http::StatusCode;
8
9use crate::error::ServerError;
10use crate::extractors::ExtractionError;
11use std::io::Write;
12
13#[diagnostic::on_unimplemented(
14 message = "`{Self}` cant be sent back as an error when used as a Handler",
15 label = "Implement `ResponseError` for `{Self}` to send it back as an error",
16 note = "any type that implements the trait `ResponseError` can be used as a result like this `Result<impl Responder<Body = BoxBody>, {Self}>`"
17)]
18pub trait ResponseError: std::fmt::Debug + std::fmt::Display + Send {
23 fn status_code(&self) -> StatusCode {
25 StatusCode::INTERNAL_SERVER_ERROR
26 }
27
28 fn error_response(&self) -> HttpResponse<BoxBody> {
30 let mut response = HttpResponse::new(self.status_code());
31
32 let mut buff = BytesMut::new();
33 let _ = write!(crate::utils::MutWriter(&mut buff), "{}", self);
34
35 let mime = mime::TEXT_PLAIN_UTF_8.to_string();
36
37 response
38 .headers_mut()
39 .insert(http::header::CONTENT_TYPE, mime.parse().unwrap());
40
41 response.set_body(BoxBody::new(buff.freeze()))
42 }
43
44 downcast_get_type_id!();
45}
46
47downcast_dyn!(ResponseError);
48
49impl ResponseError for ServerError {
50 fn status_code(&self) -> StatusCode {
51 match self {
52 ServerError::ExtractionError(err) => err.status_code(),
53 _ => StatusCode::INTERNAL_SERVER_ERROR,
54 }
55 }
56}
57
58impl ResponseError for ExtractionError {
59 fn status_code(&self) -> StatusCode {
60 StatusCode::BAD_REQUEST
61 }
62}