콘텐츠로 이동

도메인 에러 매핑 (도메인 카탈로그 → ApplicationError)

내 프로젝트에는 DOC_005, CTX_001 같은 자체 에러 코드가 있는데, SDK의 관측성(trace 이벤트 · Langfuse)은 표준 ErrorCode 8종(INVALID_INPUT, NOT_FOUND, …)만 이해합니다. 이 둘을 에러를 던질 때마다 손으로 이으면 코드가 흩어지고 trace 필드도 빠지기 쉽습니다.

make_domain_error_raiser매핑 표(카탈로그) 하나로 전용 raise 함수를 만들어 이 연결을 한곳에 모읍니다. 이후 그 함수를 한 줄 호출하면 ApplicationError 생성과 trace 필드 노출이 자동입니다.


① 한 번만 — 카탈로그 + raise 함수 정의

섹션 제목: “① 한 번만 — 카탈로그 + raise 함수 정의”
app/internals/errors.py
from llamon_agent.core.errors import (
DomainErrorSpec,
ErrorCode,
make_domain_error_raiser,
)
_CATALOG: dict[str, DomainErrorSpec] = {
"CTX_001": {"sdk_code": ErrorCode.INVALID_INPUT, "reason": "context_invalid",
"title": "요청 컨텍스트 오류", "retriable": False},
"DOC_005": {"sdk_code": ErrorCode.NOT_FOUND, "reason": "doc_name_unrecognized",
"title": "서류명 미식별", "retriable": False},
}
raise_app_error = make_domain_error_raiser(_CATALOG)

카탈로그는 도메인코드 → {sdk_code, reason, title, retriable} 매핑입니다.

필드
sdk_code표준 ErrorCode 8종 중 하나
reason기계용 사유 (snake_case 권장)
title사용자에게 보일 기본 메시지
retriable클라이언트 재시도 가능 여부
app/nodes.py
from app.internals.errors import raise_app_error
raise_app_error("DOC_005", detail="documents 빈 배열")

raise_app_error("DOC_005", detail="...") 한 줄이면 끝입니다. (카탈로그에 없는 코드를 넣으면 즉시 ValueError로 알려줍니다. 메시지를 그때그때 바꾸려면 message="..."를 추가하세요.)


위 호출이 노드에서 일어나면 NODE_ERROR · TOOL_ERROR · INVOKE_ERROR · A2A_ERROR 이벤트 최상위에 다음 필드가 별도 코드 없이 등장합니다.

필드출처
errorCode · errorReason · retriable카탈로그의 sdk_code · reason · retriable
domainCode · domainTitle함수가 자동 추가
detail + 호출 시 넘긴 **extra호출 시점

덕분에 Langfuse에서 domainCode = "DOC_005" 기준으로 바로 묶어 보거나 거를 수 있습니다.


추가 정보 붙이기 — 호출할 때 아무 키나 더 넘기면 trace에 같이 실립니다.

raise_app_error("UPS_001", bankErrorCode="0042", retryAfterMs=1500)

키 이름 바꾸기domainCode 대신 사내 컨벤션(bizCode 등)을 쓰려면:

raise_app_error = make_domain_error_raiser(
_CATALOG,
domain_code_key="bizCode",
domain_title_key="bizTitle",
)

안전장치 2가지

  • 호출할 때 errorCode · errorReason · retriable**extra로 덮어쓰려 해도 카탈로그 값이 항상 우선합니다.
  • 카탈로그의 sdk_codeErrorCode가 아니면, 운영 중이 아니라 함수를 만드는 순간 바로 TypeError로 잡힙니다(fail-fast).

상황권장
도메인 코드 3개 이상 + 일관성 필요make_domain_error_raiser (factory)
코드 0~2개 / 일회성raise_application_error 직접 호출

직접 호출도 trace 노출 효과는 동일합니다. factory는 카탈로그 일관성과 “만드는 즉시 검증”을 더해 줄 뿐입니다.

from llamon_agent.core.errors import ErrorCode, raise_application_error
raise_application_error(
ErrorCode.NOT_FOUND, "doc_name_unrecognized", domainCode="DOC_005",
)