Skip to content

Commit b8b93a0

Browse files
committed
Produce INTERNAL_ERROR observation outcome
Prior to this commit, the `DefaultExecutionRequestObservationConvention` would only produce "INTERNAL_ERROR" outcomes if the response is null or if an unresolved exception remains. The `ExceptionResolversExceptionHandler` will catch all unresolved exceptions and add them to the errors map with the `ErorType.INTERNAL_ERROR` error type. This means that the "INTERNAL_ERROR" outcome is never used. This commit ensures that this outcome is also used if at least one resolved error is of `ErorType.INTERNAL_ERROR`. Fixes gh-1065
1 parent 5ffe512 commit b8b93a0

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

spring-graphql-docs/modules/ROOT/pages/observability.adoc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ By default, the following KeyValues are created:
3232
|===
3333

3434
The `graphql.operation` KeyValue will use the custom name of the provided query, or http://spec.graphql.org/draft/#sec-Language.Operations[the standard name for the operation] if none (`"query"`, `"mutation"` or `"subscription"`).
35-
The `graphql.outcome` KeyValue will be `"SUCCESS"` if a valid GraphQL response has been sent, `"REQUEST_ERROR"` if the request could not be parsed, or `"INTERNAL_ERROR"` if no valid GraphQL response could be produced.
35+
The `graphql.outcome` KeyValue will be:
36+
37+
* `"SUCCESS"` if a valid GraphQL response has been sent and it contains no errors
38+
* `"REQUEST_ERROR"` if the request could not be parsed, or if the response contains errors (none of them being of type `org.springframework.graphql.execution.ErrorType.INTERNAL_ERROR`)
39+
* `"INTERNAL_ERROR"` if no valid GraphQL response could be produced, or if the response contains at least one error of type `org.springframework.graphql.execution.ErrorType.INTERNAL_ERROR`
3640

3741
.High cardinality Keys
3842
[cols="a,a"]

spring-graphql/src/main/java/org/springframework/graphql/observation/DefaultExecutionRequestObservationConvention.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.micrometer.common.KeyValue;
2020
import io.micrometer.common.KeyValues;
2121

22+
import org.springframework.graphql.execution.ErrorType;
2223
import org.springframework.graphql.observation.GraphQlObservationDocumentation.ExecutionRequestHighCardinalityKeyNames;
2324
import org.springframework.graphql.observation.GraphQlObservationDocumentation.ExecutionRequestLowCardinalityKeyNames;
2425

@@ -73,7 +74,10 @@ protected KeyValue outcome(ExecutionRequestObservationContext context) {
7374
if (context.getError() != null || context.getExecutionResult() == null) {
7475
return OUTCOME_INTERNAL_ERROR;
7576
}
76-
else if (context.getExecutionResult().getErrors().size() > 0) {
77+
else if (!context.getExecutionResult().getErrors().isEmpty()) {
78+
if (context.getExecutionResult().getErrors().stream().anyMatch((error) -> ErrorType.INTERNAL_ERROR.equals(error.getErrorType()))) {
79+
return OUTCOME_INTERNAL_ERROR;
80+
}
7781
return OUTCOME_REQUEST_ERROR;
7882
}
7983
return OUTCOME_SUCCESS;

spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultExecutionRequestObservationConventionTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 the original author or authors.
2+
* Copyright 2020-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,12 +19,16 @@
1919
import java.util.function.Consumer;
2020

2121
import graphql.ExecutionInput;
22+
import graphql.ExecutionResult;
2223
import graphql.ExecutionResultImpl;
24+
import graphql.GraphQLError;
2325
import graphql.execution.ExecutionId;
2426
import graphql.schema.idl.errors.QueryOperationMissingError;
2527
import io.micrometer.common.KeyValue;
2628
import org.junit.jupiter.api.Test;
2729

30+
import org.springframework.graphql.execution.ErrorType;
31+
2832
import static org.assertj.core.api.Assertions.assertThat;
2933

3034
/**
@@ -86,7 +90,8 @@ void hasOutcomeKeyValueWhenErrorOutput() {
8690
void hasOutcomeKeyValueWhenInternalError() {
8791
ExecutionRequestObservationContext context = createObservationContext(this.input, builder -> {
8892
});
89-
context.setError(new IllegalStateException("custom internal error"));
93+
GraphQLError graphQLError = GraphQLError.newError().errorType(ErrorType.INTERNAL_ERROR).message(ErrorType.INTERNAL_ERROR + " for [executionId]").build();
94+
context.setExecutionResult(ExecutionResult.newExecutionResult().addError(graphQLError).build());
9095
assertThat(this.convention.getLowCardinalityKeyValues(context)).contains(KeyValue.of("graphql.outcome", "INTERNAL_ERROR"));
9196
}
9297

0 commit comments

Comments
 (0)