Skip to content

Commit e8da721

Browse files
committed
..
1 parent 7d567a0 commit e8da721

File tree

2 files changed

+84
-88
lines changed

2 files changed

+84
-88
lines changed

lib/executor/src/execution/plan.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
response::project_by_operation,
2424
},
2525
response::{
26-
error_normalization::{add_subgraph_info_to_error, normalize_errors_for_representations},
26+
error_normalization::{add_subgraph_info_to_error, normalize_error_for_representation},
2727
graphql_error::GraphQLError,
2828
merge::deep_merge,
2929
subgraph_response::SubgraphResponse,
@@ -474,14 +474,16 @@ impl<'exec> QueryPlanExecutor<'exec> {
474474
}
475475

476476
if let Some(errors) = &response.errors {
477-
let normalized_errors = normalize_errors_for_representations(
478-
&job.subgraph_name,
479-
job.flatten_node_path.as_slice(),
480-
&job.representation_hashes,
481-
&job.filtered_representations_hashes,
482-
errors,
483-
);
484-
ctx.errors.extend(normalized_errors);
477+
for error in errors {
478+
let normalized_errors = normalize_error_for_representation(
479+
error,
480+
&job.subgraph_name,
481+
job.flatten_node_path.as_slice(),
482+
&job.representation_hashes,
483+
&job.filtered_representations_hashes,
484+
);
485+
ctx.errors.extend(normalized_errors);
486+
}
485487
}
486488
}
487489
}

lib/executor/src/response/error_normalization.rs

Lines changed: 73 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -11,100 +11,90 @@ use crate::response::graphql_error::{GraphQLError, GraphQLErrorPathSegment};
1111
* and flatten path is ['product', 'reviews', 0, 'author']
1212
* it becomes `["product", "reviews", "0", "author", "name"]`.
1313
*/
14-
pub fn normalize_errors_for_representations(
14+
pub fn normalize_error_for_representation(
15+
error: &GraphQLError,
1516
subgraph_name: &str,
1617
normalized_path: &[FlattenNodePathSegment],
1718
representation_hashes: &[u64],
1819
hashes_to_indexes: &HashMap<u64, Vec<VecDeque<usize>>>,
19-
errors: &Vec<GraphQLError>,
2020
) -> Vec<GraphQLError> {
2121
let mut new_errors: Vec<GraphQLError> = Vec::new();
22-
'error_loop: for error in errors {
23-
if let Some(path_in_error) = &error.path {
24-
if let Some(GraphQLErrorPathSegment::String(first_path)) = path_in_error.first() {
25-
if first_path == "_entities" {
26-
if let Some(GraphQLErrorPathSegment::Index(entity_index)) = path_in_error.get(1)
27-
{
28-
if let Some(representation_hash) = representation_hashes.get(*entity_index)
29-
{
30-
if let Some(indexes_in_paths) =
31-
hashes_to_indexes.get(representation_hash)
32-
{
33-
for indexes_in_path in indexes_in_paths {
34-
let mut indexes_in_path = indexes_in_path.clone();
35-
let mut real_path: Vec<GraphQLErrorPathSegment> =
36-
Vec::with_capacity(
37-
normalized_path.len() + path_in_error.len() - 2,
38-
);
39-
for segment in normalized_path {
40-
match segment {
41-
FlattenNodePathSegment::Field(field_name) => {
42-
real_path.push(GraphQLErrorPathSegment::String(
43-
field_name.to_string(),
22+
if let Some(path_in_error) = &error.path {
23+
if let Some(GraphQLErrorPathSegment::String(first_path)) = path_in_error.first() {
24+
if first_path == "_entities" {
25+
if let Some(GraphQLErrorPathSegment::Index(entity_index)) = path_in_error.get(1) {
26+
if let Some(representation_hash) = representation_hashes.get(*entity_index) {
27+
if let Some(indexes_in_paths) = hashes_to_indexes.get(representation_hash) {
28+
for indexes_in_path in indexes_in_paths {
29+
let mut indexes_in_path = indexes_in_path.clone();
30+
let mut real_path: Vec<GraphQLErrorPathSegment> =
31+
Vec::with_capacity(
32+
normalized_path.len() + path_in_error.len() - 2,
33+
);
34+
for segment in normalized_path {
35+
match segment {
36+
FlattenNodePathSegment::Field(field_name) => {
37+
real_path.push(GraphQLErrorPathSegment::String(
38+
field_name.to_string(),
39+
));
40+
}
41+
FlattenNodePathSegment::List => {
42+
if let Some(index_in_path) = indexes_in_path.pop_front()
43+
{
44+
real_path.push(GraphQLErrorPathSegment::Index(
45+
index_in_path,
4446
));
4547
}
46-
FlattenNodePathSegment::List => {
47-
if let Some(index_in_path) =
48-
indexes_in_path.pop_front()
49-
{
50-
real_path.push(GraphQLErrorPathSegment::Index(
51-
index_in_path,
52-
));
53-
}
54-
}
55-
FlattenNodePathSegment::Cast(_type_condition) => {
56-
// Cast segments are not included in the error path
57-
continue;
58-
}
5948
}
60-
}
61-
if !indexes_in_path.is_empty() {
62-
// If there are still indexes left, we need to traverse them
63-
while let Some(index) = indexes_in_path.pop_front() {
64-
real_path.push(GraphQLErrorPathSegment::Index(index));
49+
FlattenNodePathSegment::Cast(_type_condition) => {
50+
// Cast segments are not included in the error path
51+
continue;
6552
}
6653
}
67-
real_path.extend_from_slice(&path_in_error[2..]);
68-
let mut new_error = error.clone();
69-
if !real_path.is_empty() {
70-
new_error.path = Some(real_path);
54+
}
55+
if !indexes_in_path.is_empty() {
56+
// If there are still indexes left, we need to traverse them
57+
while let Some(index) = indexes_in_path.pop_front() {
58+
real_path.push(GraphQLErrorPathSegment::Index(index));
7159
}
72-
new_error =
73-
add_subgraph_info_to_error(new_error, subgraph_name);
74-
new_errors.push(new_error);
7560
}
76-
continue 'error_loop;
61+
real_path.extend_from_slice(&path_in_error[2..]);
62+
let mut new_error = error.clone();
63+
if !real_path.is_empty() {
64+
new_error.path = Some(real_path);
65+
}
66+
new_error = add_subgraph_info_to_error(new_error, subgraph_name);
67+
new_errors.push(new_error);
7768
}
69+
return new_errors;
7870
}
7971
}
8072
}
8173
}
8274
}
83-
// Use the path without indexes in case of unlocated error
84-
let mut real_path: Vec<GraphQLErrorPathSegment> = Vec::with_capacity(normalized_path.len());
85-
for segment in normalized_path {
86-
match segment {
87-
FlattenNodePathSegment::Field(field_name) => {
88-
real_path.push(GraphQLErrorPathSegment::String(field_name.to_string()));
89-
}
90-
FlattenNodePathSegment::List => {
91-
break;
92-
}
93-
FlattenNodePathSegment::Cast(_type_condition) => {
94-
// Cast segments are not included in the error path
95-
continue;
96-
}
75+
}
76+
// Use the path without indexes in case of unlocated error
77+
let mut real_path: Vec<GraphQLErrorPathSegment> = Vec::with_capacity(normalized_path.len());
78+
for segment in normalized_path {
79+
match segment {
80+
FlattenNodePathSegment::Field(field_name) => {
81+
real_path.push(GraphQLErrorPathSegment::String(field_name.to_string()));
82+
}
83+
FlattenNodePathSegment::List => {
84+
break;
85+
}
86+
FlattenNodePathSegment::Cast(_type_condition) => {
87+
// Cast segments are not included in the error path
88+
continue;
9789
}
9890
}
99-
let mut new_error = error.clone();
100-
if !real_path.is_empty() {
101-
new_error.path = Some(real_path);
102-
}
103-
new_error = add_subgraph_info_to_error(new_error, subgraph_name);
104-
105-
new_errors.push(new_error);
10691
}
107-
92+
let mut new_error = error.clone();
93+
if !real_path.is_empty() {
94+
new_error.path = Some(real_path);
95+
}
96+
new_error = add_subgraph_info_to_error(new_error, subgraph_name);
97+
new_errors.push(new_error);
10898
new_errors
10999
}
110100

@@ -158,13 +148,17 @@ fn test_normalize_errors_for_representations() {
158148
extensions: None,
159149
},
160150
];
161-
let normalized_errors = normalize_errors_for_representations(
162-
"products",
163-
&normalized_path,
164-
&representation_hashes,
165-
&indexes_in_paths,
166-
&errors,
167-
);
151+
let mut normalized_errors = Vec::new();
152+
for error in &errors {
153+
let normalized_error = normalize_error_for_representation(
154+
error,
155+
"products",
156+
&normalized_path,
157+
&representation_hashes,
158+
&indexes_in_paths,
159+
);
160+
normalized_errors.extend(normalized_error);
161+
}
168162
println!("{:?}", normalized_errors);
169163
assert_eq!(normalized_errors.len(), 2);
170164
assert_eq!(

0 commit comments

Comments
 (0)