0

I recently rewrote some GraphQL services from Java to .NET Core.

In Java, I was able to provide custom error messages to the clients using the errors.extensions in the response, ie:

{
"data": {
    "someMutation": null
},
"errors": [{
        "cause": null,
        "message": "Unauthorized",
        "httpStatusCode": 0,
        "extensions": {
            "uiMessage": "Oh no, your session expired. You'll need to login again to continue.",
            "httpStatusDescription": "Unauthorized",
            "httpStatusCode": 401
        },
        "errorType": "ValidationError",
        "path": null,
        "localizedMessage": "Unauthorized",
        "suppressed": []
    }
  ]
}

However, in .NET, I don't seem to be able to replicate this format. ErrorInfo.Extensions is added to the root of the response, not to the the Errors object itself, eg:

{
 "data": {
     "someMutation": null
 },
 "errors": [{
         "message": "Auth token not provided"
     }
 ],
 "extensions": {
     "httpStatusCode": 401,
     "httpStatusDescription": null,
     "uiMessage": "Oh no, your session expired. You'll need to login again to continue.",
 }
}

The GraphQL spec reads (ref https://spec.graphql.org/October2021/#sec-Errors, https://spec.graphql.org/October2021/#example-8b658):

GraphQL services may provide an additional entry to errors with key extensions. This entry, if set, must have a map as its value. This entry is reserved for implementors to add additional information to errors however they see fit, and there are no additional restrictions on its contents.

eg:

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [{ "line": 6, "column": 7 }],
      "path": ["hero", "heroFriends", 1, "name"],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

I created a new test project (.NET Core 3.1) using the latest versions of the libraries (GraphQL 7.1.1 et al) but am still unable to add custom properties to errors.extensions.

This is the test mutation which intentionally throws an exception:

Field<StringGraphType>("greet")
            .Argument<NonNullGraphType<StringGraphType>>("name")
            .Resolve(context => {
                try {
                    throw new Exception("Invalid input");                        
                    return "Hello " + context.GetArgument<String>("name");
                } catch(Exception ex) {
                    // This doesn't seem to get returned anywhere in the response
                    Dictionary<String, object> extraData = new Dictionary<string, object>();
                    extraData.Add("error1", "message1");

                    // Add the error to the response using the overloaded constructor
                    context.Errors.Add(new ExecutionError("Oh dear, that went wrong", extraData));

                    // This gets added to the root of the response
                    context.OutputExtensions.Add("error2", "message2");                        

                    return null;
                }
            });

the mutation to invoke it:

mutation {greet(name:"Chewbacca")}

and the response (I don't know where errors.extensions.details comes from):

{
  "errors": [
    {
      "message": "Oh dear, that went wrong",
      "extensions": {
        "details": "GraphQL.ExecutionError: Oh dear, that went wrong"
      }
    }
  ],
  "data": {
    "greet": null
  },
  "extensions": {
    "error2": "message2"
  }
}

I would imagine that the GraphQL.NET library would expose an Extensions dictionary on the ExecutionError object so one could add custom values in the usual manner, eg:

ExecutionError executionError = new ExecutionError("Oh dear, that went horribly wrong");
executionError.Extensions.Add("customError", "Your custom error here")
context.Errors.Add(executionError);

Which would result in a response similar to this:

{
"data": {
    "someMutation": null
},
"errors": [{            
        "message": "Oh dear, that went horribly wrong",            
        "extensions": {
            "customError": "Your custom error here"                
        }            
    }
  ]
}

I am hopeful that some bright individual in the community can (slap me upside the head and) point me in the right direction.

Jamiu S.
  • 5,257
  • 5
  • 12
  • 34

0 Answers0