diff --git a/crates/cache/src/lib.rs b/crates/cache/src/lib.rs index fe3de3ede..f5686222a 100644 --- a/crates/cache/src/lib.rs +++ b/crates/cache/src/lib.rs @@ -167,6 +167,7 @@ pub trait CacheStore: Send + Sync + 'static { /// [`ResBody`] has Stream type, which is not `Send + Sync`, so we need to convert it to `CachedBody`. /// If response's body is ['ResBody::Stream`], it will not be cached. #[derive(Clone, Debug)] +#[non_exhaustive] pub enum CachedBody { /// None body. None, @@ -283,12 +284,17 @@ where Some(cache) => cache, None => { ctrl.call_next(req, depot, res).await; - if !res.body.is_stream() { + if !res.body.is_stream() && !res.body.is_error() { let headers = res.headers().clone(); - let body: CachedBody = (&res.body).try_into().unwrap(); - let cached_data = CachedEntry::new(res.status_code, headers, body); - if let Err(e) = self.store.save_entry(key, cached_data).await { - tracing::error!(error = ?e, "cache failed"); + let body = TryInto::::try_into(&res.body); + match body { + Ok(body) => { + let cached_data = CachedEntry::new(res.status_code, headers, body); + if let Err(e) = self.store.save_entry(key, cached_data).await { + tracing::error!(error = ?e, "cache failed"); + } + } + Err(e) => tracing::error!(error = ?e, "cache failed"), } } return; diff --git a/crates/core/src/http/body/res.rs b/crates/core/src/http/body/res.rs index 70f5bda45..dd63c53f4 100644 --- a/crates/core/src/http/body/res.rs +++ b/crates/core/src/http/body/res.rs @@ -68,6 +68,12 @@ impl ResBody { ResBody::Error(_) => None, } } + + /// Set body to none and returns current body. + #[inline] + pub fn take(&mut self) -> ResBody { + std::mem::replace(self, ResBody::None) + } } impl Stream for ResBody {