-
Notifications
You must be signed in to change notification settings - Fork 317
Record response errors as events in Request Observations #859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello @stefaniasm, thanks for reaching out! First I would like us to be on the same page, so let's use the following example to discuss.
We'll use this mutation operation for different cases. The implementation looks like: @Controller
public class BookController {
@MutationMapping
public Book createBook(@Argument @Validated BookInput bookInput) {
// throw new IllegalStateException("this is a custom error");
return new Book(42L, "Spring for GraphQL book", new Author(12L, "Spring", "team"));
}
}
public class BookInput {
@NotNull
@Size(max=5)
private String name;
@NotNull
private Long authorId;
//...
} Exception thrown by the data fetcher itselfIf I uncomment the exception throwing in the controller itself and send the following operation:
I am getting the Server validation exceptionIf I comment again the exception throwing in the controller and this time send a document that will fail the validation because the name is too long:
I am getting the Invalid documentThis time, let's send an invalid document that will not pass the GraphQL validation:
The response is the following:
In this case, the data fetcher is never invoked and there is no "graphql.datafetcher" observation but there is a "graphql.request" observation that states that
Thanks! |
Hello @bclozel ! So best approach to collect info for GraphQl error traces is to do a custom handler/filter in order to collect High cardinality Keys from the "errors" map, right? But in this case, we won't have metrics. Did I understand correctly? |
Are you collecting this data in metrics and/or traces? Custom solutionYou can implement your own Enhancement requestHere, we could also simply consider this as an enhancement issue and add useful bits to the "graphql.request" observation. Maybe other instrumentations are doing things differently. If you can share what kind of information you would like to see in metrics and traces, I could suggest a custom implementation and directly implement the changes in Spring for GraphQL. |
I have to collect them in metrics and traces. "If you can share what kind of information you would like to see in metrics and traces" -> on short, I would like to have the error message from "error" map somewhere in order to be interpreted as an error tag. We want to be able to understand the big part of the issue directly from traces and also to have some sort of statistics about the number of issues occurred(so we also need metrics), to be aware of the message, of the fields included in the error, the type of the error (everything is in the graphQL error.message from what I noticed) If I create a custom metric named "errors" where I collect all messages from GraphQL error map, from what I tested, this metric is seen as a 'normal' metric by actuator and probably by data collectors as well. I am not sure it's possible to force it to be seen as an error tag. By error tag I mean the highlighted part (response when calling actuator/metrics/graphql.request): Thank you again! |
Hello @bclozel ! I also noticed that in the scenario described in the 'Invalid document' section, the metric added in @observed(name="metricName") is not identified/created anymore, as in a successful case. It only creates the default 'graphql.request' metric. I am testing this using the actuator/metrics/{requiredMetricName} endpoint. I think that is also because the data.fetcher metrics are not created in that case.. |
Hey @stefaniasm I believe In the meantime, I have discussed this matter with the Observability team and I will provide an update here once I have tested various options. |
Thank you! All clear now. |
Sorry for the radio silence. I've been discussing this with the Observability team, which knows much more than I do about the various backends, formats and their limitations. Our goal here is to keep using the We can't call
Instead, I've explored adding events on the GraphQL Request observation with Here is an example of that with a local experiment. When sending an invalid GraphQL request: This creates annotations on the graphql request span using the "contextual name" of the event: This also creates counters automatically under the
This adds more information to the observation and improves the situation, but we still need to decide:
|
Thanks for keeping me up to date. As a suggestion for point 2, maybe you could use parts of graphQLError.getMessage(), for example, using 'authorById' or 'heyThere' as contextual name might suffice, although this depends on the specific requirements of your project and the big picture. |
I think we will improve a bit the proposal (especially around the contextual name of span annotations) but go with it. We've discussed it this morning and thought that this is too much of a change to introduce in the current 1.2.x line as a maintenance version, so we're targeting 1.3.0 next May. |
Prior to this commit, GraphQL Request Observations would not record errors as Observation errors, because with GraphQL errors can partially affect the response and there can be multiple. Instead, an invalid request (for example) would lead to a `"graphql.outcome", "REQUEST_ERROR"` low cardinality KeyValue. In this case, developers would not know what type of error occured nor if there were multiple. This commit records all errors listed in the GraphQL as Observation.Event on the request Observation. Such events are usually handled by the tracing handler and are recorded as span annotations for traces. Other `ObservationHandler` annotations can leverage events in a different fashion. Closes spring-projectsgh-859
Prior to this commit, GraphQL Request Observations would not record errors as Observation errors, because with GraphQL errors can partially affect the response and there can be multiple. Instead, an invalid request (for example) would lead to a `"graphql.outcome", "REQUEST_ERROR"` low cardinality KeyValue. In this case, developers would not know what type of error occured nor if there were multiple. This commit records all errors listed in the GraphQL as Observation.Event on the request Observation. Such events are usually handled by the tracing handler and are recorded as span annotations for traces. Other `ObservationHandler` annotations can leverage events in a different fashion. Closes gh-859
Project details:
Spring Boot project, having:
According to this doc: https://docs.spring.io/spring-graphql/reference/observability.html#observability.server.request, by default, in case of data fetching errors, the graphql.error.type should be created and have an appropriate value.
But in case of Spring GraphQL, from what I know, read and debugged, errors (any GraphQl Error, for instance a ValidationError) are resolved and returned in "error" field in response, there is no Throwable exception thrown.
Having all this info, I noticed the following check in DefaultDataFetcherObservationConvention, when errorType is saved:
context.getError() refers to a Throwable error, which is missing in the case described above. So the key is not created in case of a ValidationError, even if I expect it to be there. I am mentioning that for a successful request, I can see the key with default value NONE created, so the configurations should be ok.
Is this the intended behaviour?
If yes..then in what case I will have the DataFetcherLowCardinalityKeyNames.ERROR_TYPE populated with a different value than the default one?
If yes, does that mean that in order to collect informations about GraphQL errors I should do something custom, like a filter or a handler?
Thank you in advance!
The text was updated successfully, but these errors were encountered: