-
Notifications
You must be signed in to change notification settings - Fork 2k
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
apollo-engine-reporting: tweaks to maskErrorDetails and rewriteError #2932
Conversation
While I think I'd like to see this merged (and am planning to build my federated metrics change on top of this, because it refactors where this code is called from) I am also raising this PR basically to try to help me understand some of the choices made in #2618 I don't understand this code in rewriteError:
This raises two questions for me: (a) Why exactly do we have an API that's allowed to return an arbitrary error, and yet if it's a GraphQLError (the expected case?) it's not allowed to change anything but the message? I'm assuming part of the point here is that it should be OK for a rewriteError to But... (b) The new feature is documented as being a replacement for |
I guess there's a tension between "want people to be be able to keep the context without having to write it" (especially for path!) and "want people to be able to delete stuff". What if at the very least, extensions was loaded from |
3337da4
to
3b85378
Compare
Yup! Generally, it was believed that users will want to mask sensitive things, or selectively not report an error.
I think the lack of a more correct As you found with
That is an important detail and should be clarified!
Seems fine to me. |
// of GraphQLError are not enumerable and won't show up in the trace | ||
// (even in the json field) anyway.) | ||
// XXX I really don't understand why we don't allow rewriteError | ||
// to rewrite extensions, which do show up in JSON. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix with the ||
solution.
) { | ||
throw new Error('rewriteError must be a function'); | ||
} else if (engine.maskErrorDetails) { | ||
engine.rewriteError = () => new GraphQLError('<masked>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had been reproducing exactly what the previous generation of maskErrorDetails
had done. I would be surprised if anyone is actually using this option in its current state, to be honest. I don't think it was ever documented, and the one person who I know asked for it claimed it missed the mark.
{ | ||
json: '{"message":"<masked>"}', | ||
json: | ||
'{"message":"<masked>","locations":[{"line":1,"column":2}],"path":["fieldWhichWillError"]}', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the original implementation just didn't have this extra detail, I think?
OK, my main goal here was verifying that we consider this to be a bug and not a feature. Thanks! |
This reimplements maskErrorDetails in terms of rewriteError. It is not quite a no-op: masked errors will now contain the path and query source string location where they occurred. This is being done at the `new ApolloServer` level because federated metrics will want to use the same normalization without using EngineReportingAgent or EngineReportingExtension.
PR description has been updated to include new changes
3b85378
to
6efa0d6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow-up commits look good. Free to merge to release-2.7.0
!
This reimplements
engine.maskErrorDetails
in terms ofengine.rewriteError
, simplifying the code path around it. It also allows rewriteError implementors slightly more control over the error they produce.Two behavior changes:
engine.rewriteError
hook has anextensions
property, that property will be used instead of the original error's extensions. We now document that changes to most otherGraphQLError
fields byengine.rewriteError
are ignored.engine.maskErrorDetails
option, deprecated byengine.rewriteError
in v2.5.0, now behaves a bit more like the new option: while all error messages will be redacted, they will still show up on the appropriate nodes in a trace.