Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to accessing GraphQL validation errors from a Relay mutation?

I'm somewhat new to GraphQL, so, still piecing all moving parts together in my head.

On my server side I'm using TypeGraphQL which uses class-validator to perform validation of the queries coming in. On the client side I'm using Relay. When the validations fail, my commitMutation call in Relay calls onError and passes a string representation of the error, but the actual response from the server looks like this:

{
  "errors": [
    {
      "message": "Argument Validation Error",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "updateCurrentUser"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "validationErrors": [
            {
              "target": {
                "name": "ueoa",
                "nickname": "ueoa",
                "email": ""
              },
              "value": "",
              "property": "email",
              "children": [],
              "constraints": {
                "isEmail": "email must be an email"
              }
            }
          ],
          "stacktrace": [
            "Error: Argument Validation Error",
            "    at Object.validateArg (C:\\Users\\pupeno\\Documents\\Flexpoint Tech\\imok\\node_modules\\type-graphql\\dist\\resolvers\\validate-arg.js:24:15)",
            "    at runMicrotasks (<anonymous>)",
            "    at processTicksAndRejections (internal/process/task_queues.js:97:5)",
            "    at async Promise.all (index 0)"
          ]
        }
      }
    }
  ],
  "data": null
}

In this case, I left the email blank and thus on errors[0].extensions.exception.validationErrors[0].constraints.isEmail I have the error: "email must be an email".

Is there a way for Relay to let me access this structure to turn this errors into UI errors for the user? Or are these errors the equivalent of a 500 and I should implement my own separate error handling (equivalent of a 401)?

I do most of my validation on the client, but uniqueness can only be on done on the server and I'm trying to figure out the protocol between the two.

like image 918
pupeno Avatar asked Jun 25 '20 05:06

pupeno


1 Answers

I don't know much about relay but I have used Typegraphql for sometime. What I can tell is that error from class-validator is nested differently from standard error (I am talking about throw new Error('this will be different'). I would advice for you to have an error formatter function on back-end so that regardless of type of error is thrown you can just return a standard graphql error. In apollo server there is option for formating error I believe other graphql servers has one too. Here is how it looks

  const apolloServer = new ApolloServer({
    formatError: (error) => error, 
  });

If class-validator's error is thrown error above will be ArgumentValidationError So if error is instance of ArgumentValidationError you need to proper format it and return to the client with all constraints values extracted and appended on message field. In this way all errors will behave the same on front-ent.

like image 90
Nux Avatar answered Nov 12 '22 18:11

Nux