AWS AppSync not displaying custom error properties with in Lambda Resolver ResponseMappingTemplate

1.1k Views Asked by At

We are trying to use custom error status codes with GraphQL so that our upstream services can better utilize the errors thrown.

We have a simple error class that extends the base Error class to include a status code:

export class ErrorWithStatusCode extends Error {
  public statusCode: number;

  constructor({
    message,
    name,
    statusCode,
  }: {
    message: string;
    name: string;
    statusCode: number;
  }) {
    super(message);

    this.name = name;
    this.statusCode = statusCode;
  }
}

export class BadRequestError extends ErrorWithStatusCode {
  constructor(message: string) {
    super({
      message,
      name: `BAD_REQUEST`,
      statusCode: 400,
    });
  }
}

And then we throw that error in our code like so:

if (existingResource) {
  throw new BadRequestError('An account with the email address already exists');
}

Inside our logs we see the Lambda invoke error:

2022-04-29T13:42:56.530Z    0e1688ac-89f1-46a7-b592-d6aeceb83fd7    ERROR   Invoke Error    
{
    "errorType": "BAD_REQUEST",
    "errorMessage": "An account with the email address already exists",
    "name": "BAD_REQUEST",
    "statusCode": 400,
    "stack": [
        "BAD_REQUEST: An account with the email address already exists",
        "    at Runtime.main [as handler] (/var/task/index.js:26908:19)",
        "    at processTicksAndRejections (internal/process/task_queues.js:95:5)"
    ]
}

Then in our VTL template, we just associate all properties outside of name and message to the custom errorInfo object as described here

$util.error(String, String, Object, Object) Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result. Additionally, an errorType field, a data field, and a errorInfo field can be specified. The data value will be added to the corresponding error block inside errors in the GraphQL response. Note: data will be filtered based on the query selection set. The errorInfo value will be added to the corresponding error block inside errors in the GraphQL response. Note: errorInfo will NOT be filtered based on the query selection set.

#if (!$util.isNull($ctx.error))
  $utils.error($ctx.error.errorMessage, $ctx.error.name, $ctx.result, $ctx.error)
#end

$utils.toJson($ctx.result)

But when we get the error back from AppSync (using the console), we do not have any additional error properties:

{
  "data": null,
  "errors": [
    {
      "path": [
        "createResource"
      ],
      "data": null,
      "errorType": null,
      "errorInfo": {
        "message": "An account with the email address already exists",
        "type": "Lambda:Unhandled"
      },
      "locations": [
        {
          "line": 2,
          "column": 5,
          "sourceName": null
        }
      ],
      "message": "A custom error was thrown from a mapping template."
    }
  ]
}

0

There are 0 best solutions below