JavaScript - 오류 확장
안녕하세요, 미래의 JavaScript 마법사 여러분! 오늘 우리는 JavaScript에서 오류를 확장하는 흥미로운 세상으로 뛰어들어 보겠습니다. 프로그래밍에 새로운 사람이라면 걱정하지 마세요 - 이 모험을 안내해 드릴 친절한 안내자가 여러분입니다. 이 수업이 끝나면, 프로처럼 자신만의 커스텀 오류를 만드는 법을 배울 것입니다!
오류 클래스 확장: 커스텀 오류 생성
기본적인 내용부터 시작해 보겠습니다. JavaScript에서 우리는 오류 객체를 만들기 위해 내장된 Error
클래스를 사용할 수 있습니다. 하지만 때로는 우리의 애플리케이션을 위해 더 구체적인 오류가 필요할 수 있습니다. 여기서 Error
클래스를 확장하는 것이 유용해집니다!
왜 오류를 확장하죠?
culinary app을 개발 중이라고 가정해 봅시다. 부엌에서 벌어지는 특정 사고에 대해 특정 오류를 만들고 싶다면 어떨까요? 일반적인 Error
를 사용할 수도 있지만, BurnedFoodError
나 OverseasonedError
가 있으면 좋지 않을까요? 우리가 이제 배우게 될 것입니다!
오류 확장의 기본 문법
간단한 예제로 시작해 보겠습니다:
class KitchenError extends Error {
constructor(message) {
super(message);
this.name = 'KitchenError';
}
}
이를 해부해 보겠습니다:
-
class
키워드를 사용하여 새로운 오류 클래스를 정의합니다. -
extends Error
는 우리의 새로운 클래스가 내장된Error
클래스를 상속해야 한다는 것을 JavaScript에 알립니다. -
constructor
에서super(message)
를 호출하여 부모Error
클래스가 올바르게 초기화되도록 합니다. -
this.name
을 설정하여 우리의 오류에 특정 이름을 부여합니다.
이제 이를 어떻게 사용할 수 있는지 보겠습니다:
try {
throw new KitchenError("The spaghetti is stuck to the ceiling!");
} catch (error) {
console.log(error.name); // 출력: KitchenError
console.log(error.message); // 출력: The spaghetti is stuck to the ceiling!
}
커스텀 속성 추가
오류를 확장하는 것의 가장 멋진 점 중 하나는 우리가 자신만의 커스텀 속성을 추가할 수 있다는 것입니다. 우리의 KitchenError
를 보강해 보겠습니다:
class KitchenError extends Error {
constructor(message, dish) {
super(message);
this.name = 'KitchenError';
this.dish = dish;
}
}
try {
throw new KitchenError("It's burning!", "lasagna");
} catch (error) {
console.log(`Oh no! The ${error.dish} is in trouble: ${error.message}`);
// 출력: Oh no! The lasagna is in trouble: It's burning!
}
이 예제에서 우리는 dish
속성을 추가하여 부엌 사고에 대해 더 많은 맥락을 제공할 수 있습니다!
특정 오류 유형 생성
이제 Error
클래스를 확장하는 법을 알고 있으므로, 부엌 앱을 위한 몇 가지 특정 오류 유형을 만들어 보겠습니다:
class BurnedFoodError extends KitchenError {
constructor(dish) {
super(`The ${dish} is burned to a crisp!`, dish);
this.name = 'BurnedFoodError';
}
}
class OverseasonedError extends KitchenError {
constructor(dish, seasoning) {
super(`The ${dish} is over-seasoned with ${seasoning}!`, dish);
this.name = 'OverseasonedError';
this.seasoning = seasoning;
}
}
이제 이 특정 오류 유형을 코드에서 사용할 수 있습니다:
function cookDinner(dish, seasoning) {
if (Math.random() < 0.5) {
throw new BurnedFoodError(dish);
} else if (Math.random() < 0.5) {
throw new OverseasonedError(dish, seasoning);
}
console.log(`Your ${dish} is perfectly cooked!`);
}
try {
cookDinner("steak", "salt");
} catch (error) {
if (error instanceof BurnedFoodError) {
console.log(`Oops! ${error.message} Time to order takeout.`);
} else if (error instanceof OverseasonedError) {
console.log(`Yikes! ${error.message} Maybe use less ${error.seasoning} next time.`);
} else {
console.log("Something went wrong in the kitchen!");
}
}
이 코드는 요리의 불확실성을 시뮬레이션하고(어떤 사람들에게는!), 다른 유형의 오류를 다른 방법으로 처리할 수 있음을 보여줍니다.
다단계 상속
이제 우리의 오류 계층 구조를 다음 단계로 업그레이드해 보겠습니다 - 문자 그대로 말이죠! 우리는 오류 유형의 체인을 만들 수 있으며, 이를 다단계 상속이라고 합니다.
부엌 오류 시스템을 확장해 보겠습니다:
class KitchenApplianceError extends KitchenError {
constructor(message, appliance) {
super(message);
this.name = 'KitchenApplianceError';
this.appliance = appliance;
}
}
class OvenError extends KitchenApplianceError {
constructor(message) {
super(message, 'oven');
this.name = 'OvenError';
}
}
class MicrowaveError extends KitchenApplianceError {
constructor(message) {
super(message, 'microwave');
this.name = 'MicrowaveError';
}
}
이 예제에서:
-
KitchenApplianceError
는KitchenError
를 상속합니다. -
OvenError
와MicrowaveError
는 모두KitchenApplianceError
를 상속합니다.
이 계층 구조를 어떻게 사용할 수 있는지 보겠습니다:
function useAppliance(appliance) {
if (appliance === 'oven') {
throw new OvenError("The oven won't heat up!");
} else if (appliance === 'microwave') {
throw new MicrowaveError("The microwave is making strange noises!");
}
}
try {
useAppliance('oven');
} catch (error) {
if (error instanceof OvenError) {
console.log(`Oven problem: ${error.message}`);
} else if (error instanceof MicrowaveError) {
console.log(`Microwave issue: ${error.message}`);
} else if (error instanceof KitchenApplianceError) {
console.log(`General appliance error with the ${error.appliance}: ${error.message}`);
} else if (error instanceof KitchenError) {
console.log(`Kitchen error: ${error.message}`);
} else {
console.log(`Unexpected error: ${error.message}`);
}
}
이 다단계 상속을 통해 우리는 매우 구체적인 오류 유형을 만들 수 있으면서도, 논리적인 계층 구조를 유지할 수 있습니다. 우리는 가장 구체적인(OvenError
)에서 가장 일반적인(Error
)까지 다양한 수준에서 오류를 잡을 수 있습니다.
메서드 표
우리가 커스텀 오류에서 사용한 주요 메서드와 속성을 요약한 표입니다:
메서드/속성 | 설명 | 예제 |
---|---|---|
constructor() |
오류 객체 초기화 | constructor(message, dish) |
super() |
부모 클래스 생성자 호출 | super(message) |
this.name |
오류 이름 설정 | this.name = 'KitchenError' |
this.[custom] |
커스텀 속성 추가 | this.dish = dish |
instanceof |
객체가 클래스의 인스턴스인지 확인 | if (error instanceof OvenError) |
오류를 확장하는 것은 단순히 오류의 예쁜 이름을 만드는 것에 관한 것이 아니라, 코드에서 다양한 오류 유형을 구조화된 방식으로 처리하는 것입니다. 이를 통해 디버깅을 더 쉽게 하고, 오류 메시지를 더 구체적이고 유용하게 만들 수 있습니다.
따라서 다음 번에 코드를 작성할 때 오류가 발생하면, 일반적인 오류를 던지지 말고 커스텀 오류를 만들어 보세요! 누구나 당신의 CodeSpaghettiError
를 개발 팀에서 이야기할 만한 주제로 만들 수 있습니다. 행복하게 코딩하시고, 모든 오류가 완벽하게 확장되길 바랍니다!
Credits: Image by storyset