Skip to content

Commit aa9fc8a

Browse files
committed
refactor all errors to error type
1 parent 7f674e5 commit aa9fc8a

File tree

9 files changed

+634
-301
lines changed

9 files changed

+634
-301
lines changed

src/builder.rs

Lines changed: 301 additions & 152 deletions
Large diffs are not rendered by default.

src/error.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use thiserror::Error;
33

44
/// Central error type for all pg_graphql operations.
55
/// This replaces string-based error handling with strongly-typed variants.
6-
#[derive(Debug, Error)]
6+
#[derive(Debug, Error, Clone)]
77
pub enum GraphQLError {
88
/// GraphQL query parsing errors
99
#[error("Parse error: {0}")]
10-
Parse(#[from] GraphQLParseError),
10+
Parse(String),
1111

1212
/// Field resolution errors
1313
#[error("Field not found: {field} on type {type_name}")]
@@ -18,7 +18,36 @@ pub enum GraphQLError {
1818
Operation { context: String, message: String },
1919
}
2020

21+
impl From<GraphQLParseError> for GraphQLError {
22+
fn from(err: GraphQLParseError) -> Self {
23+
Self::Parse(err.to_string())
24+
}
25+
}
26+
27+
impl From<String> for GraphQLError {
28+
fn from(err: String) -> Self {
29+
Self::Operation {
30+
context: "Error".to_string(),
31+
message: err,
32+
}
33+
}
34+
}
35+
36+
impl From<&str> for GraphQLError {
37+
fn from(err: &str) -> Self {
38+
Self::Operation {
39+
context: "Error".to_string(),
40+
message: err.to_string(),
41+
}
42+
}
43+
}
44+
2145
impl GraphQLError {
46+
/// Creates a parse error
47+
pub fn parse(message: impl Into<String>) -> Self {
48+
Self::Parse(message.into())
49+
}
50+
2251
/// Creates a field not found error
2352
pub fn field_not_found(field: impl Into<String>, type_name: impl Into<String>) -> Self {
2453
Self::FieldNotFound {

src/gson.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ were not provided by the user.
66
*/
77
use std::collections::HashMap;
88

9+
use crate::error::{GraphQLError, GraphQLResult};
10+
911
#[derive(Clone, Debug, PartialEq)]
1012
pub enum Value {
1113
Absent,
@@ -29,7 +31,7 @@ pub enum Number {
2931
Float(f64),
3032
}
3133

32-
pub fn json_to_gson(val: &serde_json::Value) -> Result<Value, String> {
34+
pub fn json_to_gson(val: &serde_json::Value) -> GraphQLResult<Value> {
3335
use serde_json::Value as JsonValue;
3436

3537
let v = match val {
@@ -52,9 +54,9 @@ pub fn json_to_gson(val: &serde_json::Value) -> Result<Value, String> {
5254
Value::Number(i_val)
5355
}
5456
None => {
55-
let f_val: f64 = x
56-
.as_f64()
57-
.ok_or("Failed to handle numeric user input".to_string())?;
57+
let f_val: f64 = x.as_f64().ok_or_else(|| {
58+
GraphQLError::type_error("Failed to handle numeric user input")
59+
})?;
5860
Value::Number(Number::Float(f_val))
5961
}
6062
}
@@ -71,12 +73,12 @@ pub fn json_to_gson(val: &serde_json::Value) -> Result<Value, String> {
7173
Ok(v)
7274
}
7375

74-
pub fn gson_to_json(val: &Value) -> Result<serde_json::Value, String> {
76+
pub fn gson_to_json(val: &Value) -> GraphQLResult<serde_json::Value> {
7577
use serde_json::Value as JsonValue;
7678

7779
let v = match val {
7880
Value::Absent => {
79-
return Err("Encounterd `Absent` value while transforming between GraphQL intermediate object notation and JSON".to_string())
81+
return Err(GraphQLError::internal("Encountered `Absent` value while transforming between GraphQL intermediate object notation and JSON"))
8082
},
8183
Value::Null => JsonValue::Null,
8284
Value::Boolean(x) => JsonValue::Bool(x.to_owned()),

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ fn resolve(
5858
}
5959
Err(err) => GraphQLResponse {
6060
data: Omit::Omitted,
61-
errors: Omit::Present(vec![ErrorMessage { message: err }]),
61+
errors: Omit::Present(vec![ErrorMessage {
62+
message: err.to_string(),
63+
}]),
6264
},
6365
}
6466
}

src/merge.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{collections::HashMap, hash::Hash};
33
use graphql_parser::query::{Field, Text, Value};
44
use indexmap::IndexMap;
55

6+
use crate::error::{GraphQLError, GraphQLResult};
67
use crate::parser_util::alias_or_name;
78

89
/// Merges duplicates in a vector of fields. The fields in the vector are added to a
@@ -12,7 +13,7 @@ use crate::parser_util::alias_or_name;
1213
///
1314
/// The map is an `IndexMap` to ensure iteration order of the fields is preserved.
1415
/// This prevents tests from being flaky due to field order changing between test runs.
15-
pub fn merge<'a, 'b, T>(fields: Vec<Field<'a, T>>) -> Result<Vec<Field<'a, T>>, String>
16+
pub fn merge<'a, 'b, T>(fields: Vec<Field<'a, T>>) -> GraphQLResult<Vec<Field<'a, T>>>
1617
where
1718
T: Text<'a> + Eq + AsRef<str>,
1819
T::Value: Hash,
@@ -41,23 +42,23 @@ where
4142
Ok(fields)
4243
}
4344

44-
fn can_merge<'a, T>(field_a: &Field<'a, T>, field_b: &Field<'a, T>) -> Result<bool, String>
45+
fn can_merge<'a, T>(field_a: &Field<'a, T>, field_b: &Field<'a, T>) -> GraphQLResult<bool>
4546
where
4647
T: Text<'a> + Eq + AsRef<str>,
4748
T::Value: Hash,
4849
{
4950
if field_a.name != field_b.name {
50-
return Err(format!(
51+
return Err(GraphQLError::validation(format!(
5152
"Fields `{}` and `{}` are different",
5253
field_a.name.as_ref(),
5354
field_b.name.as_ref(),
54-
));
55+
)));
5556
}
5657
if !same_arguments(&field_a.arguments, &field_b.arguments) {
57-
return Err(format!(
58+
return Err(GraphQLError::validation(format!(
5859
"Two fields named `{}` have different arguments",
5960
field_a.name.as_ref(),
60-
));
61+
)));
6162
}
6263

6364
Ok(true)

0 commit comments

Comments
 (0)