AppSync 및 Lambda를 사용하여 클라이언트 오류를 적절하게 처리하는 방법
4535 단어 appsyncprogrammingawslambda
module.exports.handler = async (event) => {
// run validation logic
return {
statusCode: 400
}
}
이렇게 하면 클라이언트의 요청에 문제가 있음을 명확하게 전달할 수 있습니다. 또한 Lambda 호출이 성공적으로 완료되도록 하여 호출이 잘못된 것으로 간주되지 않습니다. 즉, Lambda 함수에 대한 오류 알림을 트리거하지 않습니다.
안타깝게도 AppSync 및 Lambda의 경우에는 이 기능이 없습니다. 함수는 유효한 응답을 반환하거나 오류를 발생시켜야 합니다.
이는 클라이언트 오류로 인해 경고가 트리거되고 잘못된 경고를 조사하는 데 시간을 낭비하게 되고 결과적으로 이러한 경고가 발생하고alert fatigue 이러한 경고에 둔감해지기 때문에 문제가 됩니다.
해결 방법
해결 방법은 API Gateway로 수행하는 작업을 모방하고 Lambda 함수가 다음과 같은 특정 응답을 반환하도록 하는 것입니다.
{
error: {
message: "blah blah",
type: "SomeErrorType"
}
}
사용자 지정 응답 VTL 템플릿을 사용하여 이를 GraphQL 오류로 전환합니다.
if (!$util.isNull($ctx.result.error))
$util.error($ctx.result.error.message, $ctx.result.error.type)
#end
$utils.toJson($ctx.result)
이렇게 하면 Lambda 호출이 여전히 성공한 것으로 간주되어 Lambda 오류에 대한 경고를 트리거하지 않습니다.
그러나 여전히 제어 흐름 문제가 발생할 수 있습니다. 단순히 오류를 던지는 대신 항상 최상위 함수 핸들러에 무언가를 반환해야 하기 때문입니다.
다음 예를 고려하십시오.
module.exports.handler = async (event) => {
const resp = await doSomething(event)
return resp
}
async function doSomething(event) {
doValidation(event)
// do something useful here
return something
}
function doValidation(event) {
if (event.arguments.answer !== 42) {
throw new Error('wrong answer')
}
}
이것은 우리가 원하는 것이 아닙니다! 클라이언트가 잘못된 요청을 보냈기 때문에 Lambda 호출에 오류가 발생하는 것을 원하지 않습니다.
한 가지 접근 방식은 오류 상태를 명시적으로 캡처하고 항상 무언가를 반환하는 것입니다.
module.exports.handler = async (event) => {
const resp = await doSomething(event)
return resp
}
async function doSomething(event) {
const validationResp = doValidation(event)
if (validationResp.error) {
return validationResp.error
}
// do something useful here
return something
}
function doValidation(event) {
if (event.arguments.answer !== 42) {
return {
error: {
message: "wrong answer",
type: "ValidationError"
}
}
} else {
return {}
}
}
오류 상태를 명시적으로 캡처하고 참조 투명성을 유지하는 것은 좋은 일이지만 JavaScript와 같은 언어에서는 그다지 편리하거나 관용적이지 않습니다.
대신 Node.js 함수로 작업할 때 middy 미들웨어를 사용하여 특정 오류를 가로채서 처리하는 것을 선호합니다.
예를 들어 아래의
ValiationError
유형과 같은 사용자 정의 오류 유형을 정의합니다.class ValidationError extends Error {
constructor(message) {
super(message)
this.name = this.constructor.name
// This clips the constructor invocation from the stack trace
// it makes the stack trace a little nicer
Error.captureStackTrace(this, this.constructor)
}
}
그리고 미들웨어는
onError
처리기에서 이 특정 오류를 처리합니다.module.exports = () => {
return {
onError: async (request) => {
if (request.error instanceof ValidationError) {
// the response vtl template handles this case
// where the response is { error: { message, type } }
request.response = {
error: {
message: request.error.message,
type: "ValidationError"
}
}
return request.response
}
}
}
}
이제 코드의 어느 위치에서든
ValidationError
만 수행할 수 있으며 오류로 인해 Lambda 호출이 실패하지 않습니다. 대신 성공적인 응답으로 전환됩니다.{
error: {
message: "...",
type: "ValidationError"
}
}
그리고 응답 VTL 템플릿은 이를 GraphQL 오류로 바꿉니다.
if (!$util.isNull($ctx.result.error))
$util.error($ctx.result.error.message, $ctx.result.error.type)
#end
$utils.toJson($ctx.result)
짜잔! 클라이언트 오류를 정상적으로 성공적으로 처리했습니다.
Reference
이 문제에 관하여(AppSync 및 Lambda를 사용하여 클라이언트 오류를 적절하게 처리하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aws-heroes/how-to-handle-client-errors-gracefully-with-appsync-and-lambda-hbe텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)