Skip to Content
API 레퍼런스@asapjs/error에러

에러

@asapjs/error는 타입 안전한 HTTP 에러 생성과 Express 에러 처리를 위한 패키지입니다. error() 팩토리로 에러 생성자를 정의하면 구조화된 에러 응답과 Swagger 스키마 자동 등록을 함께 사용할 수 있습니다.

임포트

import { HttpError, HttpErrorBody, error, ErrorCreator, makeHttpError, errorToResponse, } from '@asapjs/error';

이 페이지에서 찾을 수 있는 것

심볼타입설명
HttpErrorBodyInterfaceHTTP 에러 응답 본문 형식
HttpErrorClass구조화된 HTTP 에러 클래스
ErrorCreator<T>Interfaceerror() 가 반환하는 호출 가능한 에러 생성자
error()Factory Function재사용 가능한 에러 생성자를 반환하는 팩토리
makeHttpError()FunctionHttpErrorBody 객체를 직접 생성
errorToResponse()Function에러 객체를 Express 응답으로 변환

Effect 라이브러리와의 통합이 필요하면 Effect Integration을 참고하세요.


HttpErrorBody

HTTP 에러 응답 본문의 형식을 정의하는 인터페이스입니다.

interface HttpErrorBody { status: number; errorCode: string; message: string; data?: Record<string, any>; }
필드타입필수설명
statusnumber필수HTTP 상태 코드
errorCodestring필수에러 식별 코드 (예: 'USER_NOT_FOUND')
messagestring필수사람이 읽을 수 있는 에러 메시지
dataRecord<string, any>선택에러에 첨부할 추가 데이터

HttpError

구조화된 HTTP 에러를 나타내는 클래스입니다. Error를 확장하고 HttpErrorBody를 구현합니다.

class HttpError extends Error implements HttpErrorBody { readonly status: number; readonly errorCode: string; readonly message: string; readonly data?: Record<string, any>; constructor( status: number, errorCode: string, message: string, data?: Record<string, any> ); toJSON(): HttpErrorBody; }

생성자

new HttpError(status: number, errorCode: string, message: string, data?: Record<string, any>)
파라미터타입설명
statusnumberHTTP 상태 코드
errorCodestring에러 식별 코드
messagestring에러 메시지
dataRecord<string, any>추가 데이터 (선택)
const err = new HttpError(404, 'NOT_FOUND', '리소스를 찾을 수 없습니다'); throw err;

toJSON()

error.toJSON(): HttpErrorBody

에러를 직렬화 가능한 HttpErrorBody 객체로 변환합니다.

const err = new HttpError(404, 'NOT_FOUND', '리소스를 찾을 수 없습니다'); console.log(err.toJSON()); // { status: 404, errorCode: 'NOT_FOUND', message: '리소스를 찾을 수 없습니다' }

HttpException과의 관계

@asapjs/router에는 레거시 에러 클래스인 HttpException이 있습니다. HttpExceptionstatusmessage만 가지며 errorCode가 없습니다. errorToResponse()HttpExceptionerrorCode: 'LEGACY_HTTP_EXCEPTION'으로 매핑합니다. 새 코드에서는 HttpErrorerror() 팩토리 사용을 권장합니다.


ErrorCreator

error() 팩토리가 반환하는 호출 가능한 에러 생성자 인터페이스입니다. 호출하면 HttpError 인스턴스를 생성하며, Swagger 문서화를 위한 메타데이터를 함께 보관합니다.

interface ErrorCreator<T = any> { (data: T): HttpError; _status: number; _code: string; _message: string; _schema: Record<string, any>; }
필드타입설명
(data)(data: T) => HttpError호출 시 HttpError 인스턴스 생성
_statusnumberHTTP 상태 코드
_codestring에러 식별 코드
_messagestring메시지 템플릿
_schemaRecord<string, any>data 필드의 타입 스키마

라우트 데코레이터의 errors 옵션에 ErrorCreator를 전달하면 Swagger 에러 응답이 자동 생성됩니다.


error()

import { error } from '@asapjs/error'; function error<T extends Record<string, any>>( status: number, code: string, message: string, schema: T ): ErrorCreator<InferTypeFromSchema<T>>

재사용 가능한 에러 생성자(ErrorCreator)를 반환하는 팩토리 함수입니다.

파라미터타입설명
statusnumberHTTP 상태 코드
codestring에러 식별 코드. Swagger 스키마 이름으로도 사용
messagestring메시지 템플릿. {key} 형식으로 data 값을 보간
schemaRecord<string, SchemaType>data 필드의 타입 스키마. TypeIs 타입 사용

메시지 보간

message 파라미터에 {key} 플레이스홀더를 넣으면 data의 값으로 자동 치환됩니다:

const UserNotFound = error( 404, 'USER_NOT_FOUND', '사용자 {userId}를 찾을 수 없습니다', { userId: TypeIs.INT() } ); throw UserNotFound({ userId: 42 }); // → message: '사용자 42를 찾을 수 없습니다'

데이터 매핑

schema에 정의된 TypeIs 타입에 따라 data 값이 자동 매핑됩니다. 예를 들어 TypeIs.INT()는 문자열 "1"을 숫자 1로 변환합니다. 이 매핑은 @asapjs/schemamapDataWithSchema()에 의해 수행됩니다.

Swagger 지연 등록

error()로 정의한 에러의 Swagger 스키마는 지연(deferred) 방식으로 등록됩니다:

  1. Swagger가 아직 준비되지 않은 경우 → 스키마를 내부 큐(pendingSchemas)에 보관
  2. markSwaggerAsReady() 호출 시 → 대기 중인 스키마를 일괄 등록
  3. Swagger 준비 후 정의된 에러 → 즉시 등록

이 메커니즘 덕분에 에러를 모듈 최상위 레벨에서 정의해도 Swagger 초기화 순서에 관계없이 스키마가 올바르게 등록됩니다.

Swagger 에러 응답 등록

라우트 데코레이터의 errors 옵션에 ErrorCreator를 전달하면 해당 엔드포인트의 Swagger 에러 응답이 자동 생성됩니다:

import { Get, ExecuteArgs, RouterController } from '@asapjs/router'; import { error } from '@asapjs/error'; import { TypeIs } from '@asapjs/schema'; const PostNotFound = error(404, 'POST_NOT_FOUND', '게시글 {postId}을 찾을 수 없습니다', { postId: TypeIs.INT(), }); export default class PostController extends RouterController { @Get('/:postId', { title: '게시글 상세 조회', response: PostInfoDto, errors: [PostNotFound], // Swagger에 에러 응답 자동 등록 }) async getPost({ path }: ExecuteArgs) { const postId = parseInt((path as any)?.postId as string, 10); const post = await this.postService.getPost(postId); if (!post) { throw PostNotFound({ postId }); } return post; } }

makeHttpError()

import { makeHttpError } from '@asapjs/error'; function makeHttpError( status: number, errorCode: string, message: string, data?: Record<string, any> ): HttpErrorBody

HttpErrorBody 형태의 순수 객체를 생성합니다. HttpError 클래스 인스턴스가 아닌 일반 객체가 필요한 경우에 사용합니다.

파라미터타입설명
statusnumberHTTP 상태 코드
errorCodestring에러 식별 코드
messagestring에러 메시지
dataRecord<string, any>추가 데이터 (선택)
const body = makeHttpError(400, 'INVALID_INPUT', '잘못된 입력입니다'); // { status: 400, errorCode: 'INVALID_INPUT', message: '잘못된 입력입니다' }

errorToResponse()

import { errorToResponse } from '@asapjs/error'; function errorToResponse(error: unknown, res: Response): void

에러 객체의 종류를 판별하여 적절한 HTTP 응답을 생성합니다. @asapjs/routerWrapper 함수가 catch 블록에서 이 함수를 호출합니다.

파라미터타입설명
errorunknown처리할 에러 객체
resResponseExpress Response 객체

에러 분류 규칙

errorToResponse()는 에러 객체의 종류에 따라 다른 응답을 생성합니다:

에러 유형조건응답 형식
HttpErrorerror instanceof HttpError{ status, errorCode, message, data? }
HttpException (레거시)statusmessage는 있지만 errorCode가 없음{ status, errorCode: 'LEGACY_HTTP_EXCEPTION', message }
HttpErrorBody 형태 객체status, errorCode, message 프로퍼티가 모두 있음객체를 그대로 전달
일반 에러 / 알 수 없는 에러위 조건에 해당하지 않음{ status: 500, errorCode: 'INTERNAL_SERVER_ERROR', message: '알 수 없는 서버 오류가 발생했습니다.' }
// Wrapper 내부에서의 호출 흐름 (packages/router/src/utils/wrapper.ts) try { const output = await cb(args); // ... } catch (err) { errorToResponse(err, res); }

전체 예제

// src/errors/user.errors.ts import { error } from '@asapjs/error'; import { TypeIs } from '@asapjs/schema'; export const UserNotFound = error( 404, 'USER_NOT_FOUND', '사용자 {userId}를 찾을 수 없습니다', { userId: TypeIs.INT() } ); export const Unauthorized = error( 401, 'UNAUTHORIZED', '인증이 필요합니다', {} ); export const InvalidInput = error( 400, 'INVALID_INPUT', '필드 {field}이(가) 유효하지 않습니다', { field: TypeIs.STRING() } );
// 사용 throw UserNotFound({ userId: 42 }); // → { status: 404, errorCode: 'USER_NOT_FOUND', // message: '사용자 42를 찾을 수 없습니다', data: { userId: 42 } } throw Unauthorized({}); // → { status: 401, errorCode: 'UNAUTHORIZED', // message: '인증이 필요합니다' }

관련 항목

Last updated on