How to send custom error in AppSync with $util.error
Asked Answered
E

1

8

I have a question about AppSync error handling. I would like to send errorInfo object along with the error response and I tried with $util.error. Per the document:

https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html

$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.

And here is what my ResponseMappingTemplate look like:

#if( $context.result && $context.result.errorMessage )
  $utils.error($context.result.errorMessage, $context.result.errorType, $context.result.data), $context.result.errorInfo)
#else
  $utils.toJson($context.result.data)
#end

Here is what I did on the resolver:

var result = {
  data: null,
  errorMessage: 'I made this error',
  errorType: 'ALWAYS_ERROR',
  errorInfo: {
    errorCode: 500,
    validations: [
      {
        fieldName: '_',
        result: false,
        reasons: [
          'Failed! Yay!'
        ]
      }
    ],
  }
};
callback(null, result);

And here is what I see in CloudWatch log:

{
    "errors": [
        "CustomTemplateException(message=I made this error, errorType=ALWAYS_ERROR, data=null, errorInfo={errorCode=500, validations=[{fieldName=_, result=false, reasons=[Failed! Yay!]}]})"
    ],
    "mappingTemplateType": "Response Mapping",
    "path": "[getError]",
    "resolverArn": "arn:aws:appsync:ap-southeast-1:....",
    "context": {
        "arguments": {},
        "result": {
            "errorMessage": "I made this error",
            "errorType": "ALWAYS_ERROR",
            "errorInfo": {
                "errorCode": 500,
                "validations": [
                    {
                        "fieldName": "_",
                        "result": false,
                        "reasons": [
                            "Failed! Yay!"
                        ]
                    }
                ]
            }
        },
        "stash": {},
        "outErrors": []
    },
    "fieldInError": true
}

And here is what I got in the response:

{
  "data": {
    "getError": null
  },
  "errors": [
    {
      "path": [
        "getError"
      ],
      "data": null,
      "errorType": "ALWAYS_ERROR",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "I made this error"
    }
  ]
}

Notice that errorInfo is null and I some how got CustomTemplateException. I suspect that is because of the 4th parameter to $utils.error. But I don’t know why. Could anyone help to point out the error or tell me whether sending custom errorInfo is possible

Exenterate answered 27/11, 2018 at 6:23 Comment(1)
Similar question for errorData: #51734496 But that doesn't answer this question for errorInfo.Exenterate
E
6

Turn out that I used the code from some tutorial which is not up to date. There are 2 versions of the Resolver Mapping Template: 2018-05-29 and 2017-02-28. So I need to change the template version to 2018-05-29 for it to work.

RequestMappingTemplate: |
  {
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
      "field": "getError",
      "arguments":  $utils.toJson($context.arguments)
    }
  }

See the changes between 2 versions here: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-changelog.html#changing-the-version-on-a-function

Exenterate answered 27/11, 2018 at 8:53 Comment(2)
This is for request mapping. Lambda functions are executing after request mapping. The error throw are captured by the response mapping.Winthorpe
@ShadabFaiz AWS response mapping templates are not versioned, instead they take their version from the request mapping template (I can't find any explicit mention of this AWS docs, but this is implied via: 1. "Given the following response mapping template....Previously with 2017-02-28..." with an example without a version field [docs.aws.amazon.com/appsync/latest/devguide/…, 2. "Common to all request mapping templates, the version field defines"[docs.aws.amazon.com/appsync/latest/devguide/…Counterreply

© 2022 - 2024 — McMap. All rights reserved.