Use real JSON in HTTP error responses

Moved from GitHub dgraph/4947

Posted by paulftw:

Experience Report

Error responses from Dgraph are too hard to parse – most useful data is in a string format that differs from error to error and most likely not documented and thus subject to change without notice.

Consider three mutations, with enterprise features and logged out user:

Access Control Error:

{ 
  set {
    <_:a> <a> <_:b> .
  }
}
================
{
  "name": "APIError",
  "url": "http://localhost:8080/mutate?commitNow=true",
  "errors": [
    {
      "message": "rpc error: code = Unauthenticated desc = no accessJwt available",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ]
}

Syntax error 1:

{ 
  set
}
================
{
  "name": "APIError",
  "url": "http://localhost:8080/mutate?commitNow=true",
  "errors": [
    {
      "message": "line -1 column -1: Invalid mutation.",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ]
}

Syntax error 2:

{ 
  set { asd }
}
================
{
  "name": "APIError",
  "url": "http://localhost:8080/mutate?commitNow=true",
  "errors": [
    {
      "message": "while lexing asd at line 1 column 0: Invalid input: a at lexText",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ]
}

Why that wasn’t great, with examples

  • All three have name: APIError
  • All three have errors.extensions.code: ErrorInvalidRequest
  • HTTP API is documented in the main docs, but neither APIError nor ErrorInvalidRequest are available in docs search, most likely because those aren’t documented.
  • All three have message field in three different formats: <msg>: <code> <desc>; <msg> <location>: <extra msg>; <location>: <msg>.
  • Both times when location was present it wasn’t correct (unrelated bug?)

What would be great

Would be great to:

  • have a code field to distinguish syntax, ACL, and other error types.
  • have documented fields for error code, line, column etc. inside the error record.
  ...
  "errors": [
    {
      "code": "SyntaxError/PermissionsError",
      "line": 3,
      "column": 7,
      "message": "Invalid input: a at lexText",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ]
  ...

martinmr commented :

This is a bit hard to do because the error messages don’t have a structure. They are just strings. But at least the errors reporting a location should have a consistent format. Marking this as accepted so that’s done.