Skip to content

Commit 0e715bd

Browse files
committed
Implement std::error::Error for FieldError
This required removing `impl From<T> for FieldError where T: Display` because it would otherwise cause a conflicting implementation. That is because `impl From<T> for T` already exists. Instead I added `impl From<String> for FieldError` and `impl From<&str> for FieldError` which should cover most use cases of the previous `impl`. I also added `FieldError::from_error` so users can convert from any error they may have.
1 parent bec1f99 commit 0e715bd

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

juniper/src/executor/mod.rs

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
use std::{borrow::Cow, cmp::Ordering, collections::HashMap, fmt::Display, sync::RwLock};
1+
use std::{
2+
borrow::Cow,
3+
cmp::Ordering,
4+
collections::HashMap,
5+
fmt::{self, Debug, Display},
6+
sync::RwLock,
7+
};
28

39
use fnv::FnvHashMap;
410

@@ -123,14 +129,26 @@ where
123129
/// Field errors are represented by a human-readable error message and an
124130
/// optional `Value` structure containing additional information.
125131
///
126-
/// They can be converted to from any type that implements `std::fmt::Display`,
127-
/// which makes error chaining with the `?` operator a breeze:
132+
/// They can be converted to from `&str` or `String` which makes error
133+
/// chaining with the `?` operator a breeze:
128134
///
129135
/// ```rust
130136
/// # use juniper::{FieldError, ScalarValue};
131137
/// fn get_string(data: Vec<u8>) -> Result<String, FieldError>
132138
/// {
133-
/// let s = String::from_utf8(data)?;
139+
/// let s = String::from_utf8(data).map_err(|e| e.to_string())?;
140+
/// Ok(s)
141+
/// }
142+
/// ```
143+
///
144+
/// You can also use `FieldError::from_error` with anything that
145+
/// implements `std::error::Error`:
146+
///
147+
/// ```rust
148+
/// # use juniper::{FieldError, ScalarValue};
149+
/// fn get_string(data: Vec<u8>) -> Result<String, FieldError>
150+
/// {
151+
/// let s = String::from_utf8(data).map_err(FieldError::from_error)?;
134152
/// Ok(s)
135153
/// }
136154
/// ```
@@ -140,13 +158,43 @@ pub struct FieldError<S = DefaultScalarValue> {
140158
extensions: Value<S>,
141159
}
142160

143-
impl<T: Display, S> From<T> for FieldError<S>
161+
impl<S> FieldError<S>
162+
where
163+
S: ScalarValue,
164+
{
165+
/// Create a `FieldError` from another error.
166+
pub fn from_error<E>(error: E) -> FieldError<S>
167+
where
168+
E: std::error::Error,
169+
{
170+
FieldError::from(error.to_string())
171+
}
172+
}
173+
174+
impl<S: Display + Debug + ScalarValue> std::error::Error for FieldError<S> {}
175+
176+
impl<S: Display + ScalarValue> fmt::Display for FieldError<S> {
177+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
178+
write!(f, "{} with extensions {}", self.message, self.extensions)
179+
}
180+
}
181+
182+
impl<S> From<&str> for FieldError<S>
144183
where
145184
S: crate::value::ScalarValue,
146185
{
147-
fn from(e: T) -> FieldError<S> {
186+
fn from(message: &str) -> FieldError<S> {
187+
FieldError::from(message.to_owned())
188+
}
189+
}
190+
191+
impl<S> From<String> for FieldError<S>
192+
where
193+
S: crate::value::ScalarValue,
194+
{
195+
fn from(message: String) -> FieldError<S> {
148196
FieldError {
149-
message: format!("{}", e),
197+
message,
150198
extensions: Value::null(),
151199
}
152200
}

0 commit comments

Comments
 (0)