"Bug là đương nhiên - Lỗi cũng đừng điên". Trong bài viết này, bạn sẽ được học cách xử lý lỗi trong JavaScript một cách khéo léo với câu lệnh try catch.
TẠI SAO PHẢI XỬ LÝ LỖI?
Đôi khi code JavaScript của bạn chạy không mượt mà như mong đợi, dẫn đến LỖI.
Có một số lý do có thể gây ra lỗi, ví dụ:
-
Người dùng có thể đã nhập giá trị không hợp lệ trong trường biểu mẫu
-
Tham chiếu đến các đối tượng hoặc hàm không tồn tại
-
Dữ liệu được gửi đến hoặc nhận từ máy chủ web không chính xác
-
Một dịch vụ mà ứng dụng cần truy cập có thể tạm thời không khả dụng
Các loại lỗi này được gọi là lỗi run-time, vì chúng xảy ra tại thời điểm chương trình chạy.
Tuy nói lỗi là chuyện thường tình, nhưng phô bày lỗi (thô lỗ) trước mặt người dùng thì không nên một chút nào.
Một ứng dụng chuyên nghiệp phải có khả năng xử lý những lỗi runtime như vậy thật khéo léo.
Thông thường, nếu lỗi không được xử lý thì máy tính sẽ thông báo những "Điều khó hiểu", "không thể đọc được" cho người dùng.
Trong nhiều trường hợp nó còn dừng chương trình một cách đột ngột khiến người dùng rất bực bội.
Ở cấp độ đơn giản, chúng ta sẽ thực hiện thông báo lỗi thông báo cho người dùng về vấn đề rõ ràng và chính xác hơn.
Hạ hỏa họ.
Giữ thiện cảm với họ.
Nói cho họ biết cần làm gì tiếp theo.
Trường hợp này, chúng ta sẽ sử dụng....
CÂU LỆNH TRY CATCH TRONG JAVASCRIPT
JavaScript cung cấp câu lệnh try catch để đặt bẫy các lỗi runtime và xử lý chúng một cách khéo léo.
Bất kỳ đoạn code nào có thể gây ra lỗi phải được đặt trong khối try
và nếu có lỗi xảy ra, đoạn code xử lý trong khối catch
sẽ sẵn sàng thực thi.
Cú pháp câu lệnh try catch trong JS:
try {
// Code có thể gặp lỗi nào đó
} catch (error) {
// Code xử lý khi lỗi xảy ra
}
Nếu lỗi xảy ra tại bất kỳ điểm nào trong khối try
, việc thực thi code ngay lập tức được chuyển từ khối try
sang khối catch
.
Nếu không có lỗi nào xảy ra trong khối try
, khối catch
sẽ bị bỏ qua và chương trình sẽ tiếp tục thực thi sau câu lệnh try catch
.
Ví dụ, nếu bạn không xử lý lỗi:
var greet = "Xin chào";
console.log(greet);
// Cố gắng truy cập biến không tồn tại
console.log(welcome);
// Nếu lỗi xảy ra, câu lệnh sau không được thực thi
console.log("Chạy mà cả có lỗi gì anh em ạ!");
Chương trình sẽ có kết quả như sau:
Xin chào
error: Uncaught ReferenceError: welcome is not defined
Rõ ràng chúng ta có 1 câu lệnh ở bên dưới.
Không những nó dừng chương trình mà còn ném cho một lỗi "Khó hiểu" như thế này.
Mình làm dev mình còn bực, huống chi khách hàng.
Vì thế, hãy xử lý lỗi một cách khéo léo bằng cách sử dụng try catch:
try {
var greet = "Xin chào";
console.log(greet);
// Cố gắng truy cập biến không tồn tại
console.log(welcome);
// Nếu lỗi xảy ra, câu lệnh sau không được thực thi
console.log("Chạy mà cả có lỗi gì anh em ạ!");
} catch (error) {
// Xử lý lỗi
console.log("Lỗi rồi anh em: " + error.message);
console.log("Đợi sửa lại sau nha!");
}
// Tiếp tục thực thi chương trình
console.log("Tiếp tục chạy chương trình!");
Kết quả ta được như thế này:
Xin chào
Lỗi rồi anh em: welcom is not defined
Đợi sửa lại sau nha!
Tiếp tục chạy chương trình
Như thế này là khá ok rồi đúng không?
> Lưu ý: Dĩ nhiên mình log thông tin ra màn hình console
trong trường hợp này không hợp lý lắm (vì người dùng đâu có đọc được). Nhưng làm thế cho dễ. Bạn có thể thay bằng alert
hoặc document.write
để in ra trên trình duyệt nhé :D.
Thông báo lỗi đã thân thiện hơn.
Chương trình không bị dừng lại.
Cơ chế làm việc là thế này:
-
Khối
try
khi chạy đến đoạn nào bị lỗi lập tức nó chuyển sang khối catch
để thực thi. Chương trình không bị dừng đột ngột mặc dù đã xảy ra lỗi.
-
Ngoài ra, hãy lưu ý rằng khối
catch
có kèm theo một mã định danh (hoạt động như tham số hàm).
-
Khi lỗi xảy ra, trình thông dịch JavaScript sẽ tạo một đối tượng lỗi. Đối tượng này sau đó được truyền như một đối số để khối
catch
xử lý tiếp.
> Lưu ý: Tên đối tượng lỗi bạn có thể đặt bất kỳ để nhận vào đối tượng lỗi mà trình thông dịch JavaScript tạo ra.
> Ghi chú: Câu lệnh try catch là một cơ chế xử lý ngoại lệ. Một ngoại lệ là tín hiệu chỉ ra rằng một số loại điều kiện hoặc lỗi đặc biệt đã xảy ra trong quá trình thực thi một chương trình. Các thuật ngữ 'ngoại lệ' và 'lỗi' thường được sử dụng thay thế cho nhau.
> Đọc thêm: TRY CATCH TRONG JAVA
CÂU LỆNH TRY CATCH FINALLY TRONG JAVASCRIPT
Câu lệnh try catch
cũng có thể có thêm mệnh đề finally
.
Code bên trong khối finally
sẽ luôn thực thi, bất kể có lỗi xảy ra trong khối try
hay không.
try {
var greet = "Xin chào.";
console.log(greet);
// Cố gắng truy cập biến không tồn tại
console.log(welcome);
// Nếu lỗi xảy ra, câu lệnh sau không được thực thi
console.log("Chạy mà cả có lỗi gì anh em ạ!");
} catch (error) {
// Xử lý lỗi
console.log("Lỗi rồi anh em: " + error.message);
console.log("Đợi sửa lại sau nha!");
} finally {
console.log("Chạy bất kể lỗi hay không!");
}
Kết quả ta được là:
Xin chào
Lỗi rồi anh em: welcom is not defined
Đợi sửa lại sau nha!
Chạy bất kể lỗi hay không!
CHỦ ĐỘNG NÉM RA LỖI VỚI THROW
Cho đến nay, chúng ta đã thấy các lỗi được trình JavaScript parser (trình phân tích cú pháp JS) tự động ném ra khi có lỗi. Tuy nhiên, bạn cũng có thể tạo lỗi theo cách thủ công bằng cách sử dụng câu lệnh throw
.
Cú pháp của câu lệnh throw
là:
throw expression;
expression
có thể là một đối tượng hoặc một giá trị của bất kỳ kiểu dữ liệu nào.
Tuy nhiên, tốt hơn là sử dụng các đối tượng, với các thuộc tính tên và thông báo.
Hàm tạo (constructor) Error()
có sẵn trong JavaScript cung cấp một cách đơn giản để tạo một đối tượng lỗi.
Hãy xem một số ví dụ:
throw x;
throw "Thiếu dữ liệu";
throw true;
throw { name: "Lỗi rồi", message: "Nhập đúng số đi!" };
throw new Error("Có gì đó sai sai!");
> Lưu ý: Nếu bạn đang sử dụng các hàm tạo lỗi được tích hợp trong JavaScript (ví dụ: Error(), TypeError(), v.v.) để tạo các đối tượng lỗi, thì thuộc tính name
giống với tên của hàm tạo và message
là bằng đối số được truyền cho hàm khởi tạo.
Chúng ta hãy thử làm một ví dụ:
// Nhắc người dùng nhập vào một số
var num = prompt("Nhập vào một số nguyên dương từ 0 - 100");
// Lưu trữ thời gian bắt đầu thực thi
var start = Date.now();
try {
if (num > 0 && num <= 100) {
alert(`Nhấn OK để tính ${num} ^ ${num}`);
alert(Math.pow(num, num)); // Tính lũy thừa
} else {
// Chủ động ném ra một lỗi
throw new Error("Giá trị nhập vào không hợp lệ");
}
} catch (e) {
alert(e.message);
} finally {
// Hiển thị thời gian thực thi
alert("Thời gian thực thi là: " + (Date.now() - start) + "ms");
}
Bạn thử chạy trên trình duyệt và nhập một số lớn hơn 100 (hoặc nhỏ hơn 0) xem thế nào?
Thông báo lỗi có thân thiện không?
Bây giờ chúng ta sẽ tạo một hàm squareRoot()
để tìm căn bậc hai của một số.
Sau đó sử dụng hàm Math.sqrt()
được tích hợp sẵn trong JavaScript để tính căn bậc 2.
Nhưng hàm này sẽ về NaN
cho các số âm mà không cung cấp thêm bất kỳ gợi ý nào về những gì đã xảy ra.
Chúng ta sẽ khắc phục sự cố này bằng cách tạo lỗi tùy chỉnh nếu gặp phải số âm:
function squareRoot(number) {
// Ném ra một lỗi nếu gặp số âm
if (number < 0) {
throw new Error("Không thể tính căn một số ÂM!");
} else {
console.log(Math.sqrt(number));
}
}
try {
squareRoot(4);
squareRoot(256);
squareRoot(-9);
squareRoot(100);
// Nếu lỗi xảy ra thì câu lệnh sau không chạy
console.log("Chạy mà chả có lỗi gì anh em ạ!");
} catch (e) {
// Xử lý lỗi
console.log(e.message);
}
> Mẹo: Về mặt lý thuyết, có thể tính căn bậc hai của số âm bằng cách sử dụng số ảo i
, trong đó i2 = -1. Do đó căn bậc hai của -4 là 2i, căn bậc hai của -9 là 3i, v.v. Nhưng số ảo không được hỗ trợ trong JavaScript.
CÁC LOẠI LỖI TRONG JAVASCRIPT
Đối tượng Error
là kiểu cơ sở của tất cả các lỗi và nó có hai thuộc tính chính:
-
message
: Chứa thông báo mô tả lỗi chi tiết hơn.
Bất kỳ lỗi nào được ném ra sẽ là một thể hiện của đối tượng Error
.
Và, có một số loại lỗi khác nhau có thể xảy ra trong quá trình thực thi một chương trình JavaScript, chẳng hạn như RangeError
, ReferenceError
, SyntaxError
, TypeError
và URIError
.
KIỂU RangeError
Kiểu lỗi RangeError
được đưa ra khi bạn sử dụng một số nằm ngoài phạm vi giá trị cho phép.
Ví dụ: Tạo một mảng có độ dài âm sẽ ném ra lỗi RangeError
.
var num = 9.69;
num.toFixed(200); // Ném ra lỗi RangeError (Chỉ cho phép từ 0 - 100)
var array = new Array(-1); // Ném ra lỗi RangeError
KIỂU ReferenceError
Một ReferenceError
thường được đưa ra khi bạn cố gắng tham chiếu hoặc truy cập một biến hoặc đối tượng không tồn tại.
Ví dụ sau đây cho thấy cách ReferenceError xảy ra.
var firstName = "NIIT";
// Truyền biến không tồn tại
console.log(firstname); // Lỗi ReferenceError
// Đối tượng không tồn tại
undefinedObj.getValues(); // Lỗi ReferenceError
// Mảng không tồn tại
nonexistentArray.length; // Lỗi ReferenceError
KIỂU SyntaxError
Lỗi SyntaxError
được đưa ra trong thời gian chạy nếu có bất kỳ sự cố cú pháp nào trong chương trình JavaScript của bạn.
Ví dụ: Nếu dấu đóng ngoặc tròn bị thiếu, hàm sẽ không đúng cú pháp v.v.
var array = ["a", "b", "c"];
document.write(array.slice(2); // SyntaxError (thiếu đóng ngoặc)
alert("Hello World!'); // SyntaxError (Sai dấu nháy)
KIỂU URIError
Lỗi URIError
được đưa ra khi bạn chỉ định một URI không hợp lệ (là viết tắt của Uniform Resource Recogfier) cho các hàm liên quan đến URI như encodeURI()
hoặc decodeURI()
, như ví dụ bên dưới:
var uri = "https://niithanoi.edu.vn/%ABC%A2%B";
decodeURI(uri); // URIError
var uri = "\uD833";
encodeURI(uri); // URIError
> Lưu ý: Có thêm một loại lỗi EvalError
được đưa ra khi lỗi xảy ra trong quá trình thực thi mã thông qua hàm eval()
. Tuy nhiên, lỗi này không được JavaScript ném ra nữa, tuy nhiên đối tượng này vẫn còn để tương thích ngược (với các phiên bản cũ).
Loại lỗi cụ thể cũng có thể được ném ra theo cách thủ công bằng cách sử dụng hàm tạo tương ứng của chúng và câu lệnh throw
.
Ví dụ: Để ném TypeError
, bạn có thể sử dụng hàm tạo TypeError()
, như sau:
var num = prompt("Nhập một số đi...");
try {
if (num != "" && num !== null && isFinite(+num)) {
alert(Math.exp(num));
} else {
throw new TypeError("Bạn chưa nhập số.");
}
} catch (e) {
alert(e.message);
console.log(e.name);
console.log(e.stack);
}
> stack
: Là một chuỗi với thông tin về chuỗi các hành vi dẫn đến lỗi. Được sử dụng cho mục đích debug.
Tạm kết
Như vậy là qua bài viết này bạn đã được tìm hiểu về cách xử lý lỗi trong JavaScript với câu lệnh try catch
và finally
.
Ngoài ra bạn cũng biết cách chủ động ném ra lỗi với throw
.
Hi vọng bài viết có ích trong quá trình HỌC LẬP TRÌNH WEB của bạn.
Chúc bạn học tốt.
---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học làm Lập trình viên. Hành động ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0914939543
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #java #php #python