1use reqwest::Error;
2use serde::Deserialize;
3use std::collections::HashMap;
4use std::fmt;
5use std::fmt::Formatter;
6
7pub struct GraphQLError {
8 message: String,
9 json: Option<Vec<GraphQLErrorMessage>>,
10}
11
12#[derive(Deserialize, Debug)]
14pub struct GraphQLErrorMessage {
15 message: String,
16 locations: Option<Vec<GraphQLErrorLocation>>,
17 extensions: Option<HashMap<String, String>>,
18 path: Option<Vec<GraphQLErrorPathParam>>,
19}
20
21#[derive(Deserialize, Debug)]
22pub struct GraphQLErrorLocation {
23 line: u32,
24 column: u32,
25}
26
27#[derive(Deserialize, Debug)]
28#[serde(untagged)]
29pub enum GraphQLErrorPathParam {
30 String(String),
31 Number(u32),
32}
33
34impl GraphQLError {
35 pub fn from_str(message: &str) -> Self {
36 Self {
37 message: String::from(message),
38 json: None,
39 }
40 }
41
42 pub fn from_json(json: Vec<GraphQLErrorMessage>) -> Self {
43 Self {
44 message: String::from("Look at json field for more details"),
45 json: Some(json),
46 }
47 }
48
49 pub fn message(&self) -> &str {
50 &self.message
51 }
52
53 pub fn json(&self) -> &Option<Vec<GraphQLErrorMessage>> {
54 &self.json
55 }
56}
57
58fn format(err: &GraphQLError, f: &mut Formatter<'_>) -> fmt::Result {
59 writeln!(f, "\nGQLClient Error: {}", err.message)?;
61
62 if err.json.is_none() {
64 return Ok(());
65 }
66
67 let errors = err.json.as_ref();
68
69 for err in errors.unwrap() {
70 writeln!(f, "Message: {}", err.message)?;
71 }
72
73 Ok(())
74}
75
76impl fmt::Display for GraphQLError {
77 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
78 format(self, f)
79 }
80}
81
82impl fmt::Debug for GraphQLError {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 format(&self, f)
85 }
86}
87
88impl std::convert::From<reqwest::Error> for GraphQLError {
89 fn from(error: Error) -> Self {
90 Self {
91 message: error.to_string(),
92 json: None,
93 }
94 }
95}