Lambda, подключенный к appsync, всегда возвращает Lambda: необработанный тип ошибки независимо от пользовательского исключения

#amazon-web-services #aws-lambda #aws-appsync

#amazon-web-services #aws-lambda #aws-appsync

Вопрос:

У меня есть лямбда-чат, который сохраняет сообщения в dynamodb. Если пользователь не авторизован для добавления сообщения, мне нужно вернуть пользовательское исключение ошибки с уникальным типом ошибки и сообщением моему клиенту.

Я настроил свою пользовательскую ошибку, используя документацию по адресу https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-lambda.html

т.е.:

 export default class ForbiddenError extends Error {
    /**
     * ForbiddenError constructor
     * @param {string} name
     * @param {string} message
     */
    constructor(name = null, message = null) {
        message = message || 'You are forbidden from performing this action.'
        super(message)
        this.name = name || 'Forbidden'
    }
}
  

и затем я выдаю ошибку внутри своего приложения через:

throw new ForbiddenError()

Когда я тестирую свой lambda локально, все работает нормально, код выдает ошибку. Я перехватываю его и вызываю

context.fail(error)

Даже когда я тестирую свою лямбду с помощью тестовой лямбды в консоли AWS, я получаю красивый ответ, содержащий как сообщение, так и тип ошибки:

 class ForbiddenError extends Error {
    constructor(message) {
        super(message)
        this.name = 'ForbiddenError'
    }
}

exports.handler = (event, context, callback) => {
    throw new ForbiddenError('You are forbidden from performing this action.')
    
    return context.fail('test');
};
  

и ошибка:

 {
  "errorType": "ForbiddenError",
  "errorMessage": "You are forbidden from performing this action.",
  "trace": [
    "ForbiddenError: You are forbidden from performing this action.",
    "    at Runtime.exports.handler (/var/task/index.js:9:21)",
    "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
  ]
}
  

но когда я вызываю свой lambda с помощью appsync, внезапно в ошибку передается только сообщение, но тип ошибки всегда один и тот же: Lambda:Unhandled т.е.:

 {
          "graphQLErrors": [
                    {
                              "path": [
                                        "storeStreamChatMessage"
                              ],
                              "data": null,
                              "errorType": "Lambda:Unhandled",
                              "errorInfo": null,
                              "locations": [
                                        {
                                                  "line": 2,
                                                  "column": 3,
                                                  "sourceName": null
                                        }
                              ],
                              "message": "You are forbidden from performing this action."
                    }
          ],
          "networkError": null,
          "message": "GraphQL error: You are forbidden from performing this action."
}
  

Шаблон сопоставления ответов тот же, что и в документации:

   ResponseMappingTemplate: |
    #if($ctx.error)
      $util.error($ctx.error.message, $ctx.error.type)
    #end

    $util.toJson($context.result)
  

Я пытался изменить $ ctx.error.type на $ ctx.error.ErrorType, но тогда ErrorType возвращается как «Пользовательская ошибка лямбда», а не «Запрещено».

Я пытался использовать методы context.fail() и обратного вызова из lambda exports.handler, оба они хорошо работают в консоли, но оба возвращают сообщение только при вызове из преобразователя appsync.

Я проверил, что context.fail(ошибка) действительно вызывается в лямбде и что исключение перехватывается с помощью оператора .catch(), прежде чем, наконец, вызвать context.fail(ошибка)

Даже cloudwatch отображает ошибку с сообщением и типом ошибки при вызове основного лямбда-выражения, поэтому я подозреваю ошибку в исключении и context.fail() возвращает

Ответ №1:

В конце я упорядочил ошибку и передал ее своим клиентам через столбец сообщений. К сожалению, когда мне удалось передать правильный тип ошибки через шаблон сопоставления ответов решателя, возвращаемая ошибка начала возвращать «Пользовательскую ошибку» в качестве возвращаемого типа ошибки.