# GraphQL Errors 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`. ## Mutation Errors 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). * There are potentially many validation errors per model attribute, but once the system encounters one `GraphQL::ExecutionError` it will stop processing that mutation. * Apollo client (and probably other GraphQL clients) have special treatment for the top-level errors field which is probably not ideal for displaying validation errors to the user. * Validation errors are meant to be displayed to the user, whereas system errors are not likely to be shown. 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. ## A Note on Inst UI 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.