#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:
В конце я упорядочил ошибку и передал ее своим клиентам через столбец сообщений. К сожалению, когда мне удалось передать правильный тип ошибки через шаблон сопоставления ответов решателя, возвращаемая ошибка начала возвращать «Пользовательскую ошибку» в качестве возвращаемого типа ошибки.