witchcraft_server/service/
error_log.rs1use std::sync::Arc;
2
3use crate::service::{Layer, Service};
17use conjure_error::Error;
18use http::{Response, StatusCode};
19use witchcraft_log::{log, Level};
20
21pub struct ErrorLogLayer;
23
24impl<S> Layer<S> for ErrorLogLayer {
25 type Service = ErrorLogService<S>;
26
27 fn layer(self, inner: S) -> Self::Service {
28 ErrorLogService { inner }
29 }
30}
31
32pub struct ErrorLogService<S> {
33 inner: S,
34}
35
36impl<S, R, B> Service<R> for ErrorLogService<S>
37where
38 S: Service<R, Response = Response<B>> + Sync,
39 R: Send,
40{
41 type Response = S::Response;
42
43 async fn call(&self, req: R) -> Self::Response {
44 let response = self.inner.call(req).await;
45
46 if let Some(error) = response.extensions().get::<Arc<Error>>() {
47 let level = match response.status() {
48 StatusCode::INTERNAL_SERVER_ERROR => Level::Error,
49 _ => Level::Info,
50 };
51
52 log!(level, "handler returned non-success", error: error);
53 }
54
55 response
56 }
57}