JavaScript - Mở rộng Lỗi

Xin chào, những pháp sư JavaScript tương lai! Hôm nay, chúng ta sẽ cùng lặn sâu vào thế giới đầy thú vị của việc mở rộng lỗi trong JavaScript. Đừng lo lắng nếu bạn mới bắt đầu học lập trình - tôi sẽ là người hướng dẫn thân thiện của bạn trong chuyến phiêu lưu này. Cuối bài học này, bạn sẽ có thể tạo ra lỗi tùy chỉnh của riêng mình như một chuyên gia!

JavaScript - Extending Errors

Mở rộng Lớp Lỗi: Tạo Lỗi Tùy chỉnh

Hãy bắt đầu từ những điều cơ bản. Trong JavaScript, chúng ta có một lớp Error内置 mà chúng ta có thể sử dụng để tạo các đối tượng lỗi. Nhưng đôi khi, chúng ta cần các lỗi cụ thể hơn cho ứng dụng của mình. Đó là lúc việc mở rộng lớp Error trở nên hữu ích!

Tại sao Mở rộng Lỗi?

Hãy tưởng tượng bạn đang xây dựng một ứng dụng nấu ăn, và bạn muốn tạo các lỗi cụ thể cho các sự cố trong bếp. Bạn có thể sử dụng lỗi chung Error, nhưng có phải sẽ tốt hơn nếu bạn có một BurnedFoodError hoặc OverseasonedError? Đó là điều chúng ta sẽ học hôm nay!

Cú pháp Cơ bản cho Mở rộng Lỗi

Hãy bắt đầu với một ví dụ đơn giản:

class KitchenError extends Error {
constructor(message) {
super(message);
this.name = 'KitchenError';
}
}

Hãy phân tích này:

  1. Chúng ta sử dụng từ khóa class để xác định lớp lỗi mới của mình.
  2. extends Error cho biết lớp mới của chúng ta nên kế thừa từ lớp Error内置.
  3. Trong constructor, chúng ta gọi super(message) để đảm bảo rằng lớp cha Error được khởi tạo đúng cách.
  4. Chúng ta đặt this.name để cho lớp lỗi của mình một tên cụ thể.

Bây giờ, hãy xem chúng ta có thể sử dụng nó như thế nào:

try {
throw new KitchenError("The spaghetti is stuck to the ceiling!");
} catch (error) {
console.log(error.name); // Xuất: KitchenError
console.log(error.message); // Xuất: The spaghetti is stuck to the ceiling!
}

Thêm các Thuộc tính Tùy chỉnh

Một trong những điều thú vị nhất khi mở rộng lỗi là chúng ta có thể thêm các thuộc tính tùy chỉnh. Hãy nâng cấp KitchenError của chúng ta:

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}`);
// Xuất: Oh no! The lasagna is in trouble: It's burning!
}

Trong ví dụ này, chúng ta đã thêm thuộc tính dish vào lỗi của mình. Điều này cho phép chúng ta cung cấp thêm ngữ cảnh về điều gì đã sai trong tai nạn nhà bếp của chúng ta!

Tạo các Loại Lỗi Cụ Thể

Bây giờ chúng ta đã biết cách mở rộng lớp Error, hãy tạo một số loại lỗi cụ thể cho ứng dụng nhà bếp của mình:

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;
}
}

Bây giờ chúng ta có thể sử dụng các loại lỗi cụ thể này trong mã của mình:

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!");
}
}

Mã này mô phỏng tính không dự đoán được của việc nấu ăn (ít nhất là đối với một số người!) và cho thấy cách chúng ta có thể xử lý các loại lỗi khác nhau theo các cách khác nhau.

Kế thừa đa cấp

Bây giờ, hãy nâng cấp hệ thống lỗi nhà bếp của chúng ta lên một cấp độ mới - thực sự! Chúng ta có thể tạo một chuỗi các loại lỗi, mỗi loại kế thừa từ loại trước đó. Điều này được gọi là kế thừa đa cấp.

Hãy mở rộng hệ thống lỗi nhà bếp của mình:

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';
}
}

Trong ví dụ này:

  • KitchenApplianceError kế thừa từ KitchenError
  • OvenErrorMicrowaveError đều kế thừa từ KitchenApplianceError

Hãy xem chúng ta có thể sử dụng hierachy này như thế nào:

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}`);
}
}

Kế thừa đa cấp cho phép chúng ta tạo ra các loại lỗi cụ thể trong khi vẫn duy trì một hierachy logic. Chúng ta có thể bắt lỗi ở các mức độ cụ thể khác nhau, từ cụ thể (OvenError) đến chung (Error).

Bảng Tóm tắt

Dưới đây là bảng tóm tắt các phương thức và thuộc tính chính chúng ta đã sử dụng trong các lỗi tùy chỉnh:

Phương thức/Thuộc tính Mô tả Ví dụ
constructor() Khởi tạo đối tượng lỗi constructor(message, dish)
super() Gọi constructor của lớp cha super(message)
this.name Đặt tên cho lỗi this.name = 'KitchenError'
this.[tùy chỉnh] Thêm thuộc tính tùy chỉnh this.dish = dish
instanceof Kiểm tra nếu một đối tượng là một instance của một lớp if (error instanceof OvenError)

Nhớ rằng, mở rộng lỗi không chỉ là việc tạo ra các tên lỗi sang trọng cho lỗi của bạn - nó còn về việc tạo ra một cách tiếp cận có cấu trúc để xử lý các loại lỗi khác nhau trong mã của bạn. Điều này có thể làm cho việc gỡ lỗi dễ dàng hơn và thông báo lỗi của bạn trở nên cụ thể và thông tin hơn.

Vậy, lần sau khi bạn đang lập trình và điều gì đó đi sai, đừng chỉ throws một lỗi chung - hãy tạo một lỗi tùy chỉnh! Ai biết được, có lẽ CodeSpaghettiError của bạn sẽ trở thành chủ đề của nhóm phát triển của bạn. Chúc bạn may mắn và mong rằng tất cả các lỗi của bạn đều được mở rộng hoàn hảo!

Credits: Image by storyset