Rework Failure2 #671

This commit is contained in:
Sunli 2021-11-05 19:05:49 +08:00
parent d64e075164
commit 4d65f9c739
2 changed files with 41 additions and 16 deletions

View File

@ -86,7 +86,7 @@ impl ServerError {
/// use async_graphql::{Failure, Error, ServerError, Pos}; /// use async_graphql::{Failure, Error, ServerError, Pos};
/// ///
/// let bytes = vec![0, 159]; /// let bytes = vec![0, 159];
/// let err: Error = String::from_utf8(bytes).map_err(Failure).unwrap_err().into(); /// let err: Error = String::from_utf8(bytes).map_err(Failure::new).unwrap_err().into();
/// let server_err: ServerError = err.into_server_error(Pos { line: 1, column: 1 }); /// let server_err: ServerError = err.into_server_error(Pos { line: 1, column: 1 });
/// assert!(server_err.concrete_error::<FromUtf8Error>().is_some()); /// assert!(server_err.concrete_error::<FromUtf8Error>().is_some());
/// ``` /// ```
@ -265,11 +265,11 @@ impl<T: Display + Send + Sync + 'static> From<T> for Error {
} }
} }
impl<T: StdError + Send + Sync + 'static> From<Failure<T>> for Error { impl From<Failure> for Error {
fn from(e: Failure<T>) -> Self { fn from(e: Failure) -> Self {
Self { Self {
message: e.0.to_string(), message: e.message,
error: Some(Arc::new(e.0)), error: Some(e.error),
extensions: None, extensions: None,
} }
} }
@ -388,7 +388,8 @@ impl<E: Display> ErrorExtensions for &E {
} }
} }
impl<T: StdError + Send + Sync + 'static> ErrorExtensions for Failure<T> { impl ErrorExtensions for Failure {
#[inline]
fn extend(self) -> Error { fn extend(self) -> Error {
Error::from(self) Error::from(self)
} }
@ -431,18 +432,24 @@ where
/// A wrapper around a dynamic error type. /// A wrapper around a dynamic error type.
#[derive(Debug)] #[derive(Debug)]
pub struct Failure<T>(pub T); pub struct Failure {
message: String,
error: Arc<dyn Any + Send + Sync>,
}
impl<T: Any + Send + Sync> From<T> for Failure<T> { impl<T: StdError + Send + Sync + 'static> From<T> for Failure {
fn from(err: T) -> Self { fn from(err: T) -> Self {
Self(err) Self {
message: err.to_string(),
error: Arc::new(err),
}
} }
} }
impl<T: Any + Send + Sync> Failure<T> { impl Failure {
/// Create a new failure. /// Create a new failure.
#[inline] #[inline]
pub fn new(err: T) -> Self { pub fn new<T: StdError + Send + Sync + 'static>(err: T) -> Self {
Self(err) From::from(err)
} }
} }

View File

@ -92,23 +92,23 @@ pub async fn test_failure() {
#[Object] #[Object]
impl Query { impl Query {
async fn failure(&self) -> Result<i32> { async fn failure(&self) -> Result<i32> {
Err(Failure(MyError::Error1).into()) Err(Failure::new(MyError::Error1).into())
} }
async fn failure2(&self) -> Result<i32> { async fn failure2(&self) -> Result<i32> {
Err(Failure(MyError::Error2))?; Err(Failure::new(MyError::Error2))?;
Ok(1) Ok(1)
} }
async fn failure3(&self) -> Result<i32> { async fn failure3(&self) -> Result<i32> {
Err(Failure(MyError::Error1) Err(Failure::new(MyError::Error1)
.extend_with(|_, values| values.set("a", 1)) .extend_with(|_, values| values.set("a", 1))
.extend_with(|_, values| values.set("b", 2)))?; .extend_with(|_, values| values.set("b", 2)))?;
Ok(1) Ok(1)
} }
async fn failure4(&self) -> Result<i32> { async fn failure4(&self) -> Result<i32> {
Err(Failure(MyError::Error2)) Err(Failure::new(MyError::Error2))
.extend_err(|_, values| values.set("a", 1)) .extend_err(|_, values| values.set("a", 1))
.extend_err(|_, values| values.set("b", 2))?; .extend_err(|_, values| values.set("b", 2))?;
Ok(1) Ok(1)
@ -166,3 +166,21 @@ pub async fn test_failure() {
}) })
); );
} }
#[tokio::test]
pub async fn test_failure2() {
#[derive(thiserror::Error, Debug, PartialEq)]
enum MyError {
#[error("error1")]
Error1,
}
struct Query;
#[Object]
impl Query {
async fn failure(&self) -> Result<i32, Failure> {
Err(MyError::Error1)?
}
}
}