use crate::service::{Layer, Service};
use conjure_error::Error;
use http::{Response, StatusCode};
use witchcraft_log::{log, Level};
pub struct ErrorLogLayer;
impl<S> Layer<S> for ErrorLogLayer {
type Service = ErrorLogService<S>;
fn layer(self, inner: S) -> Self::Service {
ErrorLogService { inner }
}
}
pub struct ErrorLogService<S> {
inner: S,
}
impl<S, R, B> Service<R> for ErrorLogService<S>
where
S: Service<R, Response = Response<B>> + Sync,
R: Send,
{
type Response = S::Response;
async fn call(&self, req: R) -> Self::Response {
let response = self.inner.call(req).await;
if let Some(error) = response.extensions().get::<Error>() {
let level = match response.status() {
StatusCode::INTERNAL_SERVER_ERROR => Level::Error,
_ => Level::Info,
};
log!(level, "handler returned non-success", error: error);
}
response
}
}