Better error message in Upsert Block

Moved from GitHub dgraph/5303

Posted by MichelDiz:

Experience Report

This could be useful to create error UI instead of a JSON response.

What you wanted to do

An upsert mutation.

The error model we currently have can be bad to read when making big queries. There are users (mainly customers) who make huge queries with many variables. The error message can get big and confusing. In addition to containing characters that hinder reading.

What you actually did

A wrong upsert block

upsert {
  query {
    me(func: eq(email, "user@company1.io")) {
      u as uid
      n as name
      a as age
      e as email
    }
  }

  mutation @if(eq(n, "Animesh")) {
    set {
      _:newNode <name> val(name) .
      _:newNode <age> val(age) .
      _:newNode <email> val(email) .
    }
  }
}

Why that wasn’t great, with examples

This error is bad for some cases.
{
  "name": "t",
  "url": "http://localhost:8080/mutate?commitNow=true",
  "errors": [
    {
      "message": "Some variables are defined but not used\nDefined:[__dgraph__0 a e n u]\nUsed:[__dgraph__0 age email name]\n",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ]
}

The answer should be something like

{
   "name": "t",
   "url": "http://localhost:8080/mutate?commitNow=true",
   "errors": [
      {
         "message": "Some variables are defined but not used",
         "Defined": "a e n u",
         "Used": "age email name",
         "extensions": {
            "code": "ErrorInvalidRequest"
         }
      }
   ]
}

Or something similar to

{
   "name": "t",
   "url": "http://localhost:8080/mutate?commitNow=true",
   "errors": [
      {
         "message": "Some variables are defined but not use",
         "Details": {
            "Defined": "a e n u",
            "Used": "age email name"
         },
         "extensions": {
            "code": "ErrorInvalidRequest"
         }
      }
   ]
}

manishrjain commented :

Would like @MichaelJCompton 's take on this.

MichaelJCompton commented :

I’m always a yes for better error messages! As long as it more quickly helps a user solve the problem with their query, then I’m for it.

This message looks like it tells you what’s wrong pretty nicely, but yes could be formatted better.

I think in terms of the structure of the message, GraphQL spec would want things moved into extensions. I also think error locations really help.

The other thing I’d wonder is it better to have “unused” - that’s what’s important, right? Why do I have to infer the actual error from the two lists?

   "errors": [
      {
         "message": "Some variables are defined but not used",
         "locations": [ {"line": x, "column": y}, ... these can really help!... ]
         "extensions": {
            "code": "ErrorInvalidRequest"
            "details": {
               "defined": [ "age", "email", "name" ],
               "used": [ "ag", "email", "name" ],
               "unused": [ "age" ]
            },
         }
      }
   ]