From d1d4aeadf48dbe3adc2b377f6c94de94e6a78da0 Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sun, 2 May 2021 22:38:50 +0100 Subject: [PATCH] If HttpResponse is already wrapping an `actix_web::Error`, return the underlying `actix_web::Error` instead of generating a dummy 500. --- actix-http/CHANGES.md | 3 +++ actix-http/src/error.rs | 6 +++++- actix-http/src/response.rs | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index f1d24c3c..46eafee5 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -14,6 +14,9 @@ ### Removed * Stop re-exporting `http` crate's `HeaderMap` types in addition to ours. [#2171] +### Fixed +* Converting an `HttpResponse` to an `Error` return the underlying `Error` if `HttpResponse` was built using `HttpResponse::from_error`. + [#2171]: https://github.com/actix/actix-web/pull/2171 diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index 39ffa29e..002331e4 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -130,7 +130,11 @@ impl From for Error { /// Convert Response to a Error impl From> for Error { fn from(res: Response) -> Error { - InternalError::from_response("", res).into() + if res.error.is_some() { + res.error.unwrap() + } else { + InternalError::from_response("", res).into() + } } } diff --git a/actix-http/src/response.rs b/actix-http/src/response.rs index a3ab1175..86659152 100644 --- a/actix-http/src/response.rs +++ b/actix-http/src/response.rs @@ -341,6 +341,7 @@ mod tests { use super::*; use crate::body::Body; use crate::http::header::{HeaderValue, CONTENT_TYPE, COOKIE}; + use crate::ResponseError; #[test] fn test_debug() { @@ -352,6 +353,26 @@ mod tests { assert!(dbg.contains("Response")); } + #[test] + fn test_response_error_conversions() { + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct MyError; + + impl std::fmt::Display for MyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "An error") + } + } + + impl ResponseError for MyError {} + + let error = MyError; + let response = Response::from_error(error.clone().into()); + let actix_error: crate::Error = response.into(); + + assert_eq!(actix_error.as_error::(), Some(&error)); + } + #[test] fn test_into_response() { let resp: Response = "test".into();