Skip to content

Strongly typed errors (part of the graph) #92

@leebenson

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions