Cũng như bất kỳ khía cạnh nào khác trong cuộc sống của chúng ta, code cũng luôn tiềm ẩn những ngoại lệ exception
nằm ngoài dự kiến của chúng ta trong quá trình vận hành. Đó là lý do mà tất cả các ngôn ngữ lập trình đều cung cấp cho chúng ta các bộ công cụ để khoanh vùng và xử lý các ngoại lệ này trong logic vận hành của code. Các bộ công cụ để thực hiện tác vụ này thường bao gồm 2 nhóm là -
- Các cú pháp giúp khoanh vùng phần code có khả năng tạo ra các ngoại lệ về logic vận hành và bắt lại các
object
mô tả ngoại lệ mà hệ thống tạo ra. Ở đây chúng ta cũng có thể khởi tạo cácobject
mô tả ngoại lệ bằng code để phát động sự kiện này nếu cần thiết. - Trình chạy thử code với tính năng
debug
có thể tạm dừng ở một điểm gần đó, và giúp chúng ta di chuyển từng bước trong tiến trình vận hành code và lần ra được logic tạo ra ngoại lệ.
Và JavaScript tại môi trường trình duyệt web cũng cung cấp cho chúng ta đầy đủ cả 2 nhóm công cụ này. Tuy nhiên thay vì dùng từ ngoại lệ exception
như nhiều ngôn ngữ lập trình phổ biến khác, thì JavaScript sử dụng từ error
- lỗi vận hành - để mô tả về các logic vận hành nằm ngoài dự tính như vậy. Chúng ta sẽ cố gắng dung hòa điểm bất đồng ngôn ngữ này bằng cách gọi là ngoại lệ trong tiếng Việt yêu dấu và error
cho các vị trí cần sử dụng trong code.
Cú pháp try .. catch .. finally
Chúng ta sẽ xem code ví dụ minh họa trước để có chất liệu thực hiện thảo luận về cú pháp này.
error.js
try { // thao tác có khả năng phát sinh ngoại lệ // về logic hoạt động của code var oneArray = []; oneArray.doSomething();
}
catch (error) { // thao tác xử lý khi có ngoại lệ phát sinh console.error(error.name); console.error(error.message);
}
finally { // thao tác dọn dẹp tài nguyên cần thiết // bất kể có ngoại lệ phát sinh hay không console.log( 'Có lõi lầm gì hay không ' + 'thì cuối cùng dòng này cũng vẫn sẽ được in ra' );
} // kết quả
// 'TypeError'
// 'oneArray.doSomething is not a function'
// 'Có lõi lầm gì hay không thì cuối cùng dòng này cũng vẫn sẽ được in ra'
Rồi... Trông cũng không quá khó hiểu. Chúng ta có 3 khối liên kết với nhau. Một dạng chuyển tiếp tác vụ hoạt động như if ... else
.
- Đầu tiên là khối
try { ... }
thực hiện công việc chính của chương trình mà chúng ta viết ra. Từ khóatry
sẽ giúp chúng ta phát hiện ra cácobject
mô tả ngoại lệerror
nếu code bên trong tạo ra khi vận hành. Sau đótry
sẽ némthrow
cácobject
mô tả ngoại lệerror
ra ngoài. - Tiếp đến là
catch
- bắt lại - đỡ lấy cácobject
mô tả ngoại lệerror
để chúng ta có thể kiểm tra thông tin mô tả ngoại lệ phát sinh và ra quyết định xử lý để phần mềm đáp ứng tốt nhất tới người dùng. - Sau cùng là
finally
- cuối cùng - thì cho dù có ngoại lệ phát sinh hay không cũng vẫn sẽ chạy phần code hỗ trợtry
dọn dẹp tài nguyên đang bày dang dở khi thực hiện công việc. Ví dụ như đóng các tệp lại, hoặc xóaobject
nào đó, hoặc thiết lập lại các công cụ màtry
sử dụng để chuẩn bị cho các lượt chạy code khác.
Các object
mô tả ngoại lệ error
Giống với các object
mô tả sự kiện event
, các object
ngoại lệ error
thuộc một class
cơ sở chung nhất là Error
- Tài liệu về class Error
của MDN - và có 2 thuộc tính căn bản là -
name
chứa chuỗi mô tả tên củaclass
cơ sở gần nhất có thể sử dụng để phân cấp các ngoại lệ và ra quyết định xử lý khác nhau. Như trong code ví dụ ở trên thì chúng ta có tênclass
làTypeError
mô tả các ngoại lệ về kiểu dữ liệu được sử dụng trong câu lệnh.message
chứa chuỗi mô tả tin nhắn thường được in raconsole
để xem thông tin mô tả về ngoại lệ. Và trong ví dụ trên là thông báooneArray.doSomething không phải là một hàm
- có nghĩa là chúng ta đang dùngoneArray.doSomething
sai logic về kiểu dữ liệu củadoSomething
.
Như vậy chúng ta cũng có thể tự tạo ra các object
mô tả ngoại lệ ở khối try
và ném ra ngoài cho catch
bắt lấy.
throw.js
try { throw new TypeError( 'Có nhầm lẫn gì đó về logic ' + ' sử dụng một giá trị nào đó' );
}
catch (error) { console.error(error.name); console.error(error.message);
}
finally { console.log( 'Có lõi lầm gì hay không ' + 'thì cuối cùng dòng này cũng vẫn sẽ được in ra' );
} // kết quả:
// 'TypeError'
// 'Có nhầm lẫn gì đó về logic sử dụng một giá trị nào đó'
// 'Có lõi lầm gì hay không thì cuối cùng dòng này cũng vẫn sẽ được in ra'
Tuyệt... Như vậy là chúng ta đã có nhóm công cụ đầu tiên để xử lý logic ngoại lệ. Bạn lưu ý là cũng giống với khi sử dụng Event
, chúng ta cũng có thể tạo ra các class
mở rộng class cơ sở Error
để mô tả các kiểu ngoại lệ khác hỗ trợ cho chương trình mà chúng ta đang xây dựng.
Chạy thử code từng bước một để lần ra logic tạo ngoại lệ và sửa chữa lại
Ở đây chúng ta có thể đặt thêm lệnh debugger;
vào đoạn code mà chúng ta nghi vấn nhất về khả năng tạo ra ngoại lệ có logic phức tạp để trình duyệt web có thể giúp chúng ta tạm dừng ở vị trí đó và chạy tiếp từng bước.
debug.js
try { debugger; var a = 0; var b = 1; throw new TypeError( 'Có nhầm lẫn gì đó về logic ' + ' sử dụng một giá trị nào đó' );
}
/* --- */
Sau đó chúng ta mở cửa sổ Sources
ở bên cạnh Console
; Rồi mở tệp learn.js
và refresh
trình duyệt web để mở lại trang web. Lúc này tiến trình chạy tệp JavaScript sẽ tạm dừng ở lệnh debugger;
, và chúng ta có thể nhấn phím F10
hoặc tổ hợp phím Ctrl + '
để di chuyển tiếp từng câu lệnh và theo dõi tiến trình chạy code để suy luận ra logic tạo ra ngoại lệ.
Như vậy là chúng ta đã thực hiện xong bài viết về chủ đề Error & Handling
. Trong bài tiếp theo, chúng ta sẽ nói về một bộ công cụ mới, giúp chúng ta làm việc dễ dàng hơn và thuận tiện hơn với các tác vụ được thực thi không đồng bộ asynchronous
. Hẹn gặp lại bạn trong bài viết tiếp theo.
(Sắp đăng tải) [JavaScript] Bài 17 - Async & Await