Skip to content

Strongly typed errors (part of the graph) #92

Description

@leebenson

Is your feature request related to a problem? Please describe.

Instead of returning an errors object when validation fails with the typical 'extensions' key, I'd like to convert a mutation return type into a union of TSuccess | FormError[], where FormError contains a strongly typed { field: String!, error: String! }.

Describe the solution you'd like

Parsing errors in a front-end client is difficult, because its shape is unknown. It could be a form error, an authentication issue, an internal server error or something else. Many web GraphQL clients treat it as a 'hard' error by default.

I'd like to validate user input, converting 'errors' into a new FormError type. Where validation on user input is relevant, the return type should be modified to include a union accommodating both the 'success' type(s) and the potential for a user error.

i.e. I'd like to wind up with something like this:

mutation LoginWithEmailAndPassword($input: LoginWithEmailAndPasswordInput!) {
  loginWithEmailAndPassword(input: $input) {
    # When user input fails... e.g. missing email address, bad password format, etc
    ... on FormError {
      field
      error
    }
    # This is the 'success' response
    ... on LoginWithEmailAndPasswordSuccess {
      jwt
    }
    # This is also a legit. response... in this case, validation passed, but
    # logging in the user failed
    ... on LoginWithEmailAndPasswordFailure {
      error
    }
  }
}

... so that if an errors does occur, it generally means something more severe than user input is off!

Describe alternatives you've considered

I could alternatively create a wrapper for a GraphQL client (I'm using React Query, FWIW) that looks for 400 responses, parses the errors key, and determines the type of error.

But this has two drawbacks:

  • The wrapper itself isn't type safe. I'm doing a lot of manual/dynamic key checking.
  • It's not supported out the box by GraphQL Code Generator - I'm using this to generate strongly typed clients, and errors are typed as TError: unknown by default.

Another alternative is to write a helper in C# that validates in the function, and converts errors into a standard FormError type. This is fine, but it requires modifying the signature of a mutation to accommodate every use-case where input is used... which is a little repetitive.

Additional context

User input errors are common, and IMO relying on the errors key with a dynamic/untyped extensions meta to determine the kind of error makes it difficult to parse what is a normal part of users interacting with the API.

Rather than creating a wrapper that catches errors and handles them at the top-level, I'd rather make form errors a first-class feature of my graph. Fluent Validation is ideal for that, but I'm unsure whether there's a simple way to have this library modify the graph to allow for a union of a 'success' and FormError[] response where it's used, or I should focus instead on creating a wrapper.

In any case, thanks for a great 'glue' library! It's very useful indeed.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions