Skip to content

Commit 0e99ac3

Browse files
committed
Implement Display 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 04bda28 commit 0e99ac3

File tree

1 file changed

+49
-7
lines changed

1 file changed

+49
-7
lines changed

juniper/src/executor/mod.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::borrow::Cow;
22
use std::cmp::Ordering;
33
use std::collections::HashMap;
4-
use std::fmt::{self, Display};
4+
use std::fmt::{self, Debug, Display};
55
use std::sync::RwLock;
66

77
use fnv::FnvHashMap;
@@ -122,14 +122,26 @@ where
122122
/// Field errors are represented by a human-readable error message and an
123123
/// optional `Value` structure containing additional information.
124124
///
125-
/// They can be converted to from any type that implements `std::fmt::Display`,
126-
/// which makes error chaining with the `?` operator a breeze:
125+
/// They can be converted to from `&str` or `String` which makes error
126+
/// chaining with the `?` operator a breeze:
127127
///
128128
/// ```rust
129129
/// # use juniper::{FieldError, ScalarValue};
130130
/// fn get_string(data: Vec<u8>) -> Result<String, FieldError>
131131
/// {
132-
/// let s = String::from_utf8(data)?;
132+
/// let s = String::from_utf8(data).map_err(|e| e.to_string())?;
133+
/// Ok(s)
134+
/// }
135+
/// ```
136+
///
137+
/// You can also use `FieldError::from_error` with anything that
138+
/// implements `std::error::Error`:
139+
///
140+
/// ```rust
141+
/// # use juniper::{FieldError, ScalarValue};
142+
/// fn get_string(data: Vec<u8>) -> Result<String, FieldError>
143+
/// {
144+
/// let s = String::from_utf8(data).map_err(FieldError::from_error)?;
133145
/// Ok(s)
134146
/// }
135147
/// ```
@@ -139,13 +151,43 @@ pub struct FieldError<S = DefaultScalarValue> {
139151
extensions: Value<S>,
140152
}
141153

142-
impl<T: Display, S> From<T> for FieldError<S>
154+
impl<S> FieldError<S>
155+
where
156+
S: ScalarValue,
157+
{
158+
/// Create a `FieldError` from another error.
159+
pub fn from_error<E>(error: E) -> FieldError<S>
160+
where
161+
E: std::error::Error,
162+
{
163+
FieldError::from(error.to_string())
164+
}
165+
}
166+
167+
impl<S: Display + Debug + ScalarValue> std::error::Error for FieldError<S> {}
168+
169+
impl<S: Display + ScalarValue> fmt::Display for FieldError<S> {
170+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171+
write!(f, "{} with extensions {}", self.message, self.extensions)
172+
}
173+
}
174+
175+
impl<S> From<&str> for FieldError<S>
143176
where
144177
S: crate::value::ScalarValue,
145178
{
146-
fn from(e: T) -> FieldError<S> {
179+
fn from(message: &str) -> FieldError<S> {
180+
FieldError::from(message.to_owned())
181+
}
182+
}
183+
184+
impl<S> From<String> for FieldError<S>
185+
where
186+
S: crate::value::ScalarValue,
187+
{
188+
fn from(message: String) -> FieldError<S> {
147189
FieldError {
148-
message: format!("{}", e),
190+
message,
149191
extensions: Value::null(),
150192
}
151193
}

0 commit comments

Comments
 (0)