Search code examples
amazon-web-servicesaws-appsync

Aws Appsync $util.error: data and errorInfo always null


I am playing with AWS AppSync. I am trying to output some error details when the request fails using the $util.error() helper (Documented here) in my resolver's response mapping template. No matter what I do, I am not able to get AppSync to output the data and errorInfo fields in the error output.

Here is the Lambda I have.

exports.handler = (event, context, callback) => {

  callback(null, {
    data: {
      name: "Test",
    },
    errorMessage: "Some error Message",
    errorType: "SomeErrorType",
    errors: {
      "foo": "bar",
      "bazz": "buzz",
    }
  })
};

As you can see, it is pretty much straight forward. I just return an object with the data, errors, errorMessage and errorType properties.

And here is my response mapping template

$utils.error($context.result.errorMessage, $context.result.errorType, $context.result.data, $context.result.errors)

Again, pretty much straight forward. I just throw an error directly using the fields coming from the Lambda.

But when I execute the query, I get this:

{
  "data": {
    "myField": null
  },
  "errors": [
    {
      "path": [
        "myField"
      ],
      "data": null,
      "errorType": "SomeErrorType",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Some error Message"
    }
  ]
}

As you can see, the errorType and message fields get populated correctly, but not the errorInfo and data ones.

Am I missing something? Why isn't this working ?

I also tried hardcoding the parameters of $util.error in the template. I got the same result...


Solution

  • As the documentation states, Note: data will be filtered based on the query selection set. So you need to return data that matches the selection set.

    So, for a basic schema that looks like:

    type Post {
        id: ID!
        title: String! 
    }
    
    type Query {
        simpleQuery: Post
    }
    
    schema {
        query: Query
    }
    

    And a query:

    query {
      simpleQuery {
        title   // Note this selection set
      }
    }
    

    And a response mapping template:

    $utils.error($context.result.errorMessage, $context.result.errorType, $context.result.data, $context.result.errors)
    

    With a Lambda code:

    exports.handler = (event, context, callback) => {
    
      callback(null, {
        data: {
          title: "Test",   // The same selection set
        },
        errorMessage: "Some error Message",
        errorType: "SomeErrorType",
        errors: {
          "foo": "bar",
          "bazz": "buzz",
        }
      })
    };
    

    It will return:

    {
      "data": {
        "badOne": null
      },
      "errors": [
        {
          "path": [
            "badOne"
          ],
          "data": {
            "title": "Test"
          },
          "errorType": "SomeErrorType",
          "errorInfo": null,
          "locations": [
            {
              "line": 8,
              "column": 3,
              "sourceName": null
            }
          ],
          "message": "Some error Message"
        }
      ]
    }