graphqlresponseaws-appsyncvtlaws-appsync-resolver

AWS Appsync + VTL template. Template transformation yielded an empty response


When I send a mutation request with invalid data, I get the following body:

{
  "data": {
    "updateForm": null
  },
  "errors": [
    {
      "path": [
        "updateForm"
      ],
      "data": null,
      "errorType": "MappingTemplate",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Template transformation yielded an empty response."
    }
  ]
}

All I expect is a message and a code:

{"statusCode":400, "message":"No changes that can be applied to the form"}

My VTL template :

#set($slideTypeMap = {
    "image": "ImageSlide",
    "text": "TextSlide",
    "question": "QuestionSlide",
    "video": "VideoSlide"})

#set($result = $util.parseJson($context.result.body))
#if($result.slides)
    #foreach($slide in $result.slides)
      #set($typeName = $slideTypeMap.get($slide.type))
      $util.quiet($slide.put("__typename", $typeName))
    #end
#end

#if($context.result.statusCode == 200)
    $util.toJson($result)
#else
    $utils.appendError($context.result.body, "$context.result.statusCode")
#end

appsync log:

{
    "logType": "ResponseMapping",
    "path": [
        "updateForm"
    ],
    "fieldName": "updateForm",
    "resolverArn": "",
    "requestId": "",
    "context": {
        "arguments": {
            "id": "e499ad6487ca416081ecc51d959e0fa4",
            "input": {
                "name": "Image"
            }
        },
        "result": {
            "headers": {
                "Apigw-Requestid": "",
                "content-length": "73",
                "Content-Type": "application/json",
                "Date": "Fri, 28 Jul 2023 13:30:30 GMT"
            },
            "statusCode": 400,
            "body": "{\"statusCode\":400,\"message\":\"No changes that can be applied to the form\"}"
        },
        "stash": {},
        "outErrors": [
            {
                "message": "{\"statusCode\":400,\"message\":\"No changes that can be applied to the form\"}",
                "type": "400"
            }
        ]
    },
    "fieldInError": true,
    "errors": [
        "Unable to transform the template: Template transformation yielded an empty response.."
    ],

I can't just return body data, because I have a Form returned in the scheme with id, name... and an error appears, and it is possible to return a null value for id, name... Me need to return the message and code that came from the API to Appsync

All I expect is a message and a code:

"statusCode":400, "message":"No changes that can be applied to the form"

Solution

  • From the AppSync Resolver mapping template utility reference/Utility helpers in $util

    $util.appendError(String) Appends 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. Unlike $util.error(String), the template evaluation will not be interrupted, so that data can be returned to the caller.

    The important part is:

    Unlike $util.error(String), the template evaluation will not be interrupted.

    That means that your resolver "appends" error information without sending back the response.

    If you replace $utils.appendError($context.result.body, "$context.result.statusCode") by $utils.error($context.result.body, "$context.result.statusCode") it should work.