doc/ui/graphq_validation_errors.md
The GraphQL spec describes a top-level errors key
(https://facebook.github.io/graphql/June2018/#sec-Errors). It is useful
for fatal errors that prevent an operation from returning data. The Ruby
GraphQL gem automatically populates errors whenever there is a
synatactical error, or when a resolver returns a GraphQL::ExecutionError.
For fatal errors (like lack of permission), we return a
GraphQL::ExecutionError (populating the top-level errors field).
There are a number of reasons why we wouldn't want to use the top-level errors field for user-facing errors (like validations).
GraphQL::ExecutionError it will stop
processing that mutation.Instead, the common solution for handling these types of errors is to
include an errors key as part of the mutation response. There doesn't
yet seem to be any consensus around a common format for the shape of these
errors.
The primary source of validation errors in Canvas are the rails validations
defined in our models. The simplest way to expose those would be to add an
errors key that is a list of {attribute, message} pairs. Some
validations do not directly correspond to a GraphQL field (either because
it's not a field exposed in GraphQL, or the attribute has been renamed), so
we'll need way to either map those attribute names appropriately, or return
a generic object-wide error message (generic error messages could be
indicated by any error with a null attribute).
A different way to express errors would be to have a mutation-specific error type for each mutation. The error shape could then look something like {attribute1 => [message1, message2], attribute2 => [message1], ...}. The big downside to this approach is that consuming this form of errors would require enumerating all possible attributes at query time which feels burdensome.
Inst UI form components take a "message" attribute that is used to display errors. We will want some kind of general purpose helper function that extracts the validation errors from a mutation response and bundles them in a format more consumable by Instructure UI.