Skip to content

Commit 9166ff8

Browse files
committed
graphql_client: impl Display for GraphQLError
This formats the error as a compiler-like output line.
1 parent f6b7f9c commit 9166ff8

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ categories = ["network-programming", "web-programming", "wasm"]
1111
[dependencies]
1212
failure = "0.1"
1313
graphql_query_derive = {path = "./graphql_query_derive", version = "0.4.0"}
14+
itertools = "0.7"
1415
serde = "1.0"
1516
serde_derive = "1.0"
1617
serde_json = "1.0"

src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![deny(warnings)]
66
#![deny(missing_docs)]
77

8+
extern crate itertools;
89
extern crate serde;
910
#[macro_use]
1011
extern crate serde_derive;
@@ -17,6 +18,9 @@ extern crate serde_json;
1718
pub use graphql_query_derive::*;
1819

1920
use std::collections::HashMap;
21+
use std::fmt::{self, Display};
22+
23+
use itertools::Itertools;
2024

2125
/// A convenience trait that can be used to build a GraphQL request body.
2226
///
@@ -109,6 +113,15 @@ pub enum PathFragment {
109113
Index(i32),
110114
}
111115

116+
impl Display for PathFragment {
117+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118+
match *self {
119+
PathFragment::Key(ref key) => write!(f, "{}", key),
120+
PathFragment::Index(ref idx) => write!(f, "{}", idx),
121+
}
122+
}
123+
}
124+
112125
/// An element in the top-level `errors` array of a response body.
113126
///
114127
/// This tries to be as close to the spec as possible.
@@ -189,6 +202,25 @@ pub struct Error {
189202
pub extensions: Option<HashMap<String, serde_json::Value>>,
190203
}
191204

205+
impl Display for Error {
206+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207+
// Use `/` as a separator like JSON Pointer.
208+
let path = self.path
209+
.as_ref()
210+
.map(|fragments| format!("{}", fragments.iter().format("/")))
211+
.unwrap_or_else(|| "<query>".to_string());
212+
213+
// Get the location of the error. We'll use just the first location for this.
214+
let loc = self.locations
215+
.as_ref()
216+
.and_then(|locations| locations.iter().next())
217+
.cloned()
218+
.unwrap_or_else(Location::default);
219+
220+
write!(f, "{}:{}:{}: {}", path, loc.line, loc.column, self.message)
221+
}
222+
}
223+
192224
/// The generic shape taken by the responses of GraphQL APIs.
193225
///
194226
/// This will generally be used with the `ResponseData` struct from a derived module.

0 commit comments

Comments
 (0)