12/08/2018, 16:08

Xử lý lỗi với try - catch trong Javascript

Trong tất cả các ngôn ngữ lập trình việc quản lý lỗi và xuất thông báo lỗi là điều không thể thiếu, nó tránh trường hợp dữ liệu error đi sâu vào DB, chết chương trình và làm sai nghiệp vụ và giảm thời gian điều tra fix bug. Try - Catch là cấu trúc không còn xa lạ gì trong các ngôn ngữ lập trình ...

Trong tất cả các ngôn ngữ lập trình việc quản lý lỗi và xuất thông báo lỗi là điều không thể thiếu, nó tránh trường hợp dữ liệu error đi sâu vào DB, chết chương trình và làm sai nghiệp vụ và giảm thời gian điều tra fix bug.

Try - Catch là cấu trúc không còn xa lạ gì trong các ngôn ngữ lập trình như C#, và trong Javascript cũng cung cấp cho chúng ta cú pháp này để xử lý và xuất ra thông báo lỗi.

try {
    // Quăng lỗi ra
        throw("Noi dung loi");  
    } catch (e){
    // Đón nhận lỗi và in ra
    // Vị trí này chỉ chạy khi ở try có quăng lỗi hoặc ở try 
    // sử dụng sai cú pháp ...
    console.log(e.message);
} finally{
    // Cuối cùng chạy cái này
    // Luôn luôn chạy sau cùng
    console.log('End of try cache');
}

Câu lệnh try chứa một khối try, chứa một hay nhiều câu lệnh ({} phải luôn được sử dụng, cũng cho các câu lệnh đơn), và ít nhất một mệnh đề catch hoặc mệnh đề cuối cùng, hoặc cả hai. Nghĩa là, có ba dạng của câu lệnh try: 1. try...catch 2. try...finally 3. try...catch...finally Mệnh đề catch chứa các câu lệnh xác định phải làm gì nếu một ngoại lệ bị ném trong khối try. Đó là, bạn muốn thử khối để thành công, và nếu nó không thành công và bạn muốn kiểm soát để vượt qua đến khối catch. Nếu bất kỳ câu lệnh nào trong khối try (hoặc trong một hàm được gọi là từ bên trong khối try) sẽ ném ra một ngoại lệ, điều khiển ngay lập tức chuyển sang mệnh đề catch. Nếu không có ngoại lệ được ném vào khối try, mệnh đề catch được bỏ qua.

Mệnh đề finally thực hiện sau khi khối try và catch clause (s) thực hiện nhưng trước các câu lệnh sau câu try. Nó luôn luôn thực hiện, bất kể một ngoại lệ đã được ném ra hay bị bắt.

Bạn có thể xếp một hoặc nhiều câu lệnh try. Nếu một khối try bên trong không có một điều khoản bắt, mệnh đề catch câu lệnh đóng của câu lệnh đã được nhập.

Như vậy vị trí finally sẽ luôn luôn được thực thi và sẽ thực thi cuối cùng. Với finally bạn có thể sử dụng hoặc không đều được. Riêng trong catch sẽ có một tham số truyền vào và tham số này sẽ chứa thông tin của lỗi và ta sử dụng biến này để lấy message.

Ví dụ: Sử dụng biến chưa định nghĩa, nếu bình thường thì chương trình bị dừng nhưng do ta sử dụng try - catch nên chương trình vẫn hoạt động bình thường.

    try {
        // Sử dụng biến message chưa được định nghĩa
        console.log(message);  
    } catch (e){
        console.log(e.message);
    }

Nếu chạy đoạn code này lên thì sẽ nhận được thông báo là biến message chưa được định nghĩa (message is not defined). Ví dụ: Sử dụng sai cú pháp nhưng chương trình vẫn chạy

    try {
        fadsfas
        fasdfas
        fsda
    } catch (e){
        console.log(e.message);
    } finally{
        console.log('End');
    }

Chương trình này nếu chạy lên thì xuất hiện dòng chữ 'fadsfas is not defined' và đoạn code trong finally vẫn hoạt động bình thường, điều này chứng tỏ chương trình không bị dừng.

Để tiện cho việc quản lý lỗi thì thông thường chúng ta sẽ viết một lớp thông báo lỗi, ví dụ dưới đây dùng để quản lý việc thông báo lỗi cho người dùng.

function UserError(){
     
    this.throwLogin = function(){
        throw new Error('Invalid username and password');
    };
     
    this.throwSession = function(){
        throw new Error('Your request is timeout');
    };
     
    return this;
}

Để sử dụng thì chúng ta làm như sau:

var username = 'thehalfheart';
var password = 'admin@';
try {
    if (username !== 'admin' || password != 'admin@'){
        var UserError = new UserError();
        UserError.throwLogin();
    }
}catch (e){
    console.log(e.message);
}

Mệnh đề cuối cùng chứa các câu lệnh để thực hiện sau khi khối try và catch clause (s) thực hiện. Lưu ý rằng mệnh đề cuối cùng thực thi bất kể có ngoại lệ được ném ra hay không. Ngoài ra, nếu một ngoại lệ được ném ra, các câu lệnh trong mệnh đề cuối thực hiện ngay cả khi không có điều khoản bắt giữ các ngoại lệ. Bạn có thể sử dụng mệnh đề cuối cùng để làm cho kịch bản của bạn không thành công khi một ngoại lệ xảy ra; ví dụ: để thực hiện công việc dọn dẹp chung, bạn có thể cần phải giải phóng một tài nguyên mà tập lệnh của bạn đã buộc.

Ví dụ sau mở tệp và sau đó thực hiện các câu lệnh sử dụng tệp (phía máy chủ JavaScript cho phép bạn truy cập tệp). Nếu ngoại lệ được ném ra trong khi tệp mở, mệnh đề cuối cùng sẽ đóng tệp trước khi tập lệnh không thành công. Đoạn mã cuối cùng cũng được thực hiện khi trả về rõ ràng từ try hoặc catch block.

openMyFile();
try {
   // tie up a resource
   writeMyFile(theData);
}
finally {
   closeMyFile(); // always close the resource
}

Nếu khối cuối trả về một giá trị, giá trị này trở thành giá trị trả lại của toàn bộ sản phẩm try-catch-finally, bất kể giá trị trả về nào trong các khối try và catch. Điều này bao gồm các trường hợp ngoại lệ được ném vào bên trong khối catch:

(function() {
  try {
    try {
      throw new Error('oops');
    }
    catch (ex) {
      console.error('inner', ex.message);
      throw ex;
    }
    finally {
      console.log('finally');
      return;
    }
  }
  catch (ex) {
    console.error('outer', ex.message);
  }
})();

// Output:
// "inner" "oops"
// "finally"

Lời khuyên là với những website chỉ sử dụng Javascript để xây dựng hiệu ứng thì bạn có thể không dùng try - catch, nhưng với những website sử dụng công nghệ mới như NodeJS hoặc cácFramework như AngularJS thì ban nên sử dụng.

0