Bỏ qua để đến nội dung

Exception Handling (Xử Lý Ngoại Lệ)

Exception Handling là cơ chế quản lý các tình huống bất thường khi chạy chương trình — những tình huống khiến luồng thực thi bình thường không thể tiếp tục an toàn. Khi lỗi được ném (throw), JavaScript sẽ ngắt luồng hiện tại và “unwind” call stack cho đến khi gặp catch; nếu không có, chương trình kết thúc trong trạng thái lỗi.


throw chủ động ném lỗi để dừng luồng bình thường và chuyển sang cơ chế bắt lỗi.


throw expression;
function parseAge(x) {
const n = Number(x);
if (!Number.isInteger(n) || n < 0) {
throw new RangeError("Age must be a non-negative integer");
}
return n;
}
parseAge(-5); // RangeError: Age must be a non-negative integer
parseAge("abc"); // RangeError: Age must be a non-negative integer

try

Vùng code có thể phát sinh lỗi

catch

Bắt và xử lý lỗi nếu try ném ra

finally

Luôn chạy sau cùng — dù có lỗi, return, hay break


try {
// code có thể gây lỗi
} catch (error) {
// xử lý lỗi
} finally {
// dọn dẹp — luôn chạy
}

try {
const data = JSON.parse('{"x":1}');
console.log(data.x); // 1
} catch (e) {
console.error("JSON invalid:", e.message);
} finally {
console.log("Xong"); // luôn chạy
}


LoạiKhi nào xảy ra
ErrorLỗi chung
TypeErrorSai kiểu dữ liệu (null.foo, gọi non-function)
RangeErrorGiá trị ngoài phạm vi (new Array(-1))
ReferenceErrorBiến chưa khai báo
SyntaxErrorCú pháp sai (thường lúc parse)
URIErrordecodeURI('%') — URI không hợp lệ

try {
undeclaredVar;
} catch (e) {
console.log(e.name); // "ReferenceError"
console.log(e.message); // "undeclaredVar is not defined"
console.log(e.stack); // full stack trace
}

class AuthError extends Error {
constructor(message, cause) {
super(message, { cause }); // Error.cause (ES2022)
this.name = "AuthError";
this.code = "AUTH_FAILED";
}
}
function authenticate(token) {
if (!token) throw new AuthError("Token missing");
// ...
}

Thêm ngữ cảnh vào lỗi gốc mà không mất thông tin:

try {
await saveToDB(item);
} catch (e) {
throw new Error("Failed to save order", { cause: e });
// caller có thể truy cập: error.cause → lỗi gốc
}

Luôn throw Error object

Không throw string/number — cần name, message, stack để debug

Không nuốt lỗi

Log rồi rethrow nếu không thể xử lý triệt để ở tầng hiện tại

Throw đúng loại

Tham số sai → TypeError/RangeError; auth sai → custom AuthError

Bọc lỗi (wrapping)

Dùng { cause } để thêm ngữ cảnh khi ném lại lỗi


Cấu trúcMô tảGhi nhớ
throwNém lỗi, dừng luồngLuôn throw Error object
tryVùng có thể lỗiĐặt code “nguy hiểm” ở đây
catch(e)Bắt và xử lý lỗiCheck instanceof nếu cần
finallyLuôn chạy sau cùngDọn dẹp — đừng return ở đây
Error.causeChuỗi lỗi (ES2022)Giữ nguyên lỗi gốc qua nhiều tầng