프로그래밍백엔드 개발자

TypeScript에서 사용자 정의 오류(커스텀 에러) 메커니즘이 어떻게 작동하는지 설명하세요. 사용자 정의 오류 클래스를 올바르게 선언하는 방법, 왜 그 타입을 지정해야 하는지, 'instanceof'와 오류 직렬화 문제를 피하는 방법은 무엇인지요?

Hintsage AI 어시스턴트로 면접 통과

답변.

문제의 역사: JavaScript에서 표준 오류는 Error 클래스를 통해 설명됩니다. 대규모 TypeScript 프로젝트에서는 상황을 정확하게 처리하기 위해 자체 오류 계층 구조를 사용하는 것이 중요하지만, 타입, 상속 및 'instanceof'의 동작과 관련하여 주의해야 할 사항이 있습니다.

문제: Error로부터 상속할 때 어려움이 발생할 수 있습니다. 프로토타입이 손실되고, 'instanceof'가 잘못 작동하며, 타입이 부정확하게 설명될 수 있고, 직렬화 시 stack trace가 손실되는 경우가 많습니다. 속성을 명시적으로 지정하지 않으면 오류 처리에서 버그가 발생할 수 있습니다.

해결책: Error 클래스를 확장하여 사용자 정의 오류를 올바르게 정의해야 합니다. 이름을 명시적으로 작성하고, 프로토타입을 수동으로 복원하며(ES5 및 CommonJS로 컴파일할 때 중요함), 오류 필드를 타입화해야 합니다.

코드 예:

class ValidationError extends Error { code: number; constructor(message: string, code: number = 400) { super(message); Object.setPrototypeOf(this, ValidationError.prototype); this.name = 'ValidationError'; this.code = code; } } function process(user: string) { if (!user) throw new ValidationError('User required', 401); }

주요 특징:

  • 트랜스파일 시에도 'instanceof'를 지원할 수 있도록 프로토타입을 명시적으로 복원.
  • 사용자 정의 오류 속성의 타입화.
  • 오류의 각 논리 그룹에 대한 개별 클래스.

함정이 있는 질문.

Object.setPrototypeOf(this, ...) 호출을 생략할 수 없는 이유는 무엇인가요?

Object.setPrototypeOf(this, Class.prototype)를 호출하지 않으면, ES5/CommonJS 또는 Babel로 컴파일할 경우 ValidationError에 대한 'instanceof'가 작동하지 않습니다. 이로 인해 ValidationError를 catch하는 블록이 오류를 포착하지 못하게 됩니다.

class CustomErr extends Error {} const err = new CustomErr('msg'); console.log(err instanceof CustomErr); // setPrototypeOf 없이는 false

사용자 정의 오류에서 name 필드를 생략 가능할까요?

this.name 속성을 설정하지 않으면 오류 스택 및 로그에 표시되는 내용이 부정확해져 원인 찾기가 어렵고 오류 분류가 힘들어집니다.

오류를 직렬화 가능하게 만들어야 하나요? 그렇다면 어떻게?

오류는 올바르게 직렬화되어야 합니다(예: 로깅 또는 네트워크 전송을 위해). 그렇지 않으면 JSON.stringify(new Error())가 message와 stack을 제공하지 않습니다. toJSON 메서드를 재정의해야 합니다.

class SerializableError extends Error { toJSON() { return { name: this.name, message: this.message, stack: this.stack }; } }

타입 오류 및 안티 패턴

  • Object.setPrototypeOf 누락으로 인해 'instanceof'가 잘못 작동함
  • name 및 사용자 정의 속성 무시
  • toJSON 구현 없이 오류 직렬화: stack/message 손실

실제 사례

부정적인 케이스

프로젝트에서 просто class MyError extends Error를 구현하고 프로토타입을 복원하지 않았습니다. 오류는 if (err instanceof MyError)로 포착했으나 작동하지 않아 코드가 조용히 치명적인 상황 처리를 건너뛰었습니다.

장점:

  • 코드가 간결하게 보임
  • 보일러플레이트가 없었음

단점:

  • instanceof가 작동하지 않음
  • 예외가 올바르게 로깅되지 않음
  • ts->js 트랜스파일러 변경 시 호환성 문제 발생

긍정적인 케이스

올바른 CustomError를 구현하고 name, code 및 toJSON을 명시적으로 설정했습니다. 다양한 오류 타입에 대한 처리를 테스트로 커버하여 로깅과 catch 핸들러에서 오류 구조가 명확해져 결함 탐색 시간이 감소했습니다.

장점:

  • 명확한 타입 계층 구조
  • 신뢰할 수 있는 직렬화
  • 브라우저와 Node.js 간의 크로스 플랫폼 호환성

단점:

  • 각 CustomError 클래스에서 템플릿 로직이 생김