AWS Lambda API에서 에러 처리와 상태 코드 설계 정리

Sue·2025년 7월 24일
0
post-thumbnail

AWS Lambda API에서 에러 처리와 상태 코드 설계 정리

목차

  1. 왜 에러 처리가 중요한가?
  2. Lambda API에서의 응답 구조 이해
  3. 주요 HTTP 상태 코드 의미와 사용 시점
  4. 실전 예외 처리 구조 (try/except)
  5. 일관된 응답 포맷 설계
  6. CloudWatch 로그와 연계
  7. 실무 팁 요약

1. 왜 에러 처리가 중요한가?

API 서버는 항상 다양한 요청을 받는다.

그 중에는 잘못된 요청도 있고, 권한이 없는 사용자 요청도 있고, 시스템 내부에서 예기치 않게 터지는 오류도 있다.

에러 처리는 단순히 "오류를 잡는 것"이 아니라, 사용자에게 문제의 원인을 명확히 전달하고, 시스템 상태를 안전하게 유지하는 행위다.

  • 에러 처리가 없으면: 사용자는 "500 Internal Server Error"만 보고 문제 원인을 알 수 없음
  • 에러 처리가 잘 되어 있으면: "필수 필드가 누락되었습니다"처럼 사용자 친화적 피드백 가능

2. Lambda API에서의 응답 구조

Lambda에서 API Gateway를 통해 호출되는 함수는 다음 구조로 응답을 반환해야 한다:

{
  "statusCode": 200,
  "body": "{\"message\": \"hello\"}",
  "headers": {
    "Content-Type": "application/json"
  }
}
  • statusCode: HTTP 상태 코드
  • body: 문자열 형태의 JSON
  • headers: JSON 형식임을 명시

주의: body는 JSON 객체가 아니라, 문자열(stringified JSON) 이어야 함


3. 주요 HTTP 상태 코드 정리

상태 코드의미언제 쓰는가?
200 OK정상 응답요청 처리 성공 시
400 Bad Request잘못된 요청필수 파라미터 누락, 타입 오류 등
401 Unauthorized인증 실패로그인 또는 토큰 누락 시
403 Forbidden권한 없음유효한 유저지만 접근 권한이 없음
404 Not Found리소스 없음없는 ID로 조회할 때 등
422 Unprocessable Entity요청 구조는 맞지만 의미상 문제유효하지 않은 값이 들어왔을 때
500 Internal Server Error시스템 내부 오류예기치 않은 예외 발생 시

4. try/except 기반 실전 예외 처리 구조

from http import HTTPStatus
from aws_lambda_powertools.logging import Logger
import json

logger = Logger()

def handler(event, context):
    try:
        name = event.get("queryStringParameters", {}).get("name")

        if not name:
            return {
                "statusCode": HTTPStatus.BAD_REQUEST,
                "body": json.dumps({"message": "Missing required parameter: name"})
            }

        return {
            "statusCode": HTTPStatus.OK,
            "body": json.dumps({"message": f"Hello, {name}!"})
        }

    except ValueError as ve:
        logger.warning(f"Validation failed: {ve}")
        return {
            "statusCode": HTTPStatus.UNPROCESSABLE_ENTITY,
            "body": json.dumps({"message": str(ve)})
        }

    except Exception as e:
        logger.exception("Unhandled error")
        return {
            "statusCode": HTTPStatus.INTERNAL_SERVER_ERROR,
            "body": json.dumps({"message": "Internal server error"})
        }

포인트 정리

  • try: 정상 흐름 처리
  • except ValueError: 유효성 관련 예외
  • except Exception: 시스템 오류 등 모든 예외 캐치
  • logger.warning, logger.exception: CloudWatch 로그로 기록

5. 일관된 응답 포맷 설계

에러 메시지가 항상 다른 구조로 나가면 클라이언트에서 처리하기 어렵다.
따라서 아래와 같은 통일된 구조로 API 응답을 구성하는 것이 좋다:

{
  "code": 400,
  "message": "필수 파라미터 누락",
  "detail": "name 파라미터는 필수입니다"
}

또는 간단히:

{
  "message": "Not authorized"
}

Pydantic을 활용하면 응답 모델도 일관되게 정의할 수 있다:

from pydantic import BaseModel

class ErrorResponse(BaseModel):
    message: str
    code: int

6. CloudWatch 로그와 연계

에러를 반환하는 것도 중요하지만, 무엇이 왜 에러였는지 로그로 남겨야 추후 디버깅이 가능하다.

aws_lambda_powertools.loggingLogger를 사용하면 structured logging도 지원된다.

logger.warning("유효하지 않은 입력: %s", invalid_input)
logger.exception("예상치 못한 오류 발생")

→ 이후 CloudWatch 콘솔에서 Lambda 로그 확인 가능


7. 실무 적용 팁 요약

설명
상태 코드 표를 만들어 두고 팀에서 공유코드 리뷰/테스트 시 기준 마련
에러 메시지는 사용자 기준에서 친절하게"KeyError" 대신 "입력 값이 잘못되었습니다"
모든 예외를 except Exception: 으로 처리하지 말고, 예측 가능한 오류는 따로 구분400 / 422 / 403은 명확하게 나눠주기
개발 단계에서 logger.exception 적극 사용배포 후 문제 추적에 핵심

마무리

에러 처리는 단순한 예외 캐치가 아니라, 서비스의 신뢰성과 사용성에 직접적인 영향을 주는 품질 요소다.

특히 Lambda 기반 API처럼 프레임워크 없이 동작하는 환경에서는 상태 코드 설계, 메시지 구조화, 로그 기록이 개발자의 책임이라는 점에서 더욱 중요하다.

profile
AI/ML Engineer

0개의 댓글