1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 01:32:57 +01:00

Add support for downcasting response errors (#986)

* Add support for downcasting response errors

* Added test for error casting
This commit is contained in:
Armin Ronacher 2019-07-18 13:25:50 +02:00 committed by Nikolay Kim
parent fbdda8acb1
commit 29098f8397

View File

@ -4,6 +4,7 @@ use std::io::Write;
use std::str::Utf8Error;
use std::string::FromUtf8Error;
use std::{fmt, io, result};
use std::any::TypeId;
pub use actix_threadpool::BlockingError;
use actix_utils::timeout::TimeoutError;
@ -51,6 +52,11 @@ impl Error {
pub fn as_response_error(&self) -> &dyn ResponseError {
self.cause.as_ref()
}
/// Similar to `as_response_error` but downcasts.
pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T> {
ResponseError::downcast_ref(self.cause.as_ref())
}
}
/// Error that can be converted to `Response`
@ -73,6 +79,22 @@ pub trait ResponseError: fmt::Debug + fmt::Display {
);
resp.set_body(Body::from(buf))
}
#[doc(hidden)]
fn __private_get_type_id__(&self) -> TypeId where Self: 'static {
TypeId::of::<Self>()
}
}
impl ResponseError + 'static {
/// Downcasts a response error to a specific type.
pub fn downcast_ref<T: ResponseError + 'static>(&self) -> Option<&T> {
if self.__private_get_type_id__() == TypeId::of::<T>() {
unsafe { Some(&*(self as *const ResponseError as *const T)) }
} else {
None
}
}
}
impl fmt::Display for Error {
@ -1044,6 +1066,16 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK);
}
#[test]
fn test_error_casting() {
let err = PayloadError::Overflow;
let resp_err: &ResponseError = &err;
let err = resp_err.downcast_ref::<PayloadError>().unwrap();
assert_eq!(err.to_string(), "A payload reached size limit.");
let not_err = resp_err.downcast_ref::<ContentTypeError>();
assert!(not_err.is_none());
}
#[test]
fn test_error_helpers() {
let r: Response = ErrorBadRequest("err").into();