2013-06-14 24 views
8

Tôi đang phát triển gói Node.js nhỏ có chứa trình phân tích cú pháp. Nó ném ngay sau khi nó phát hiện một vấn đề không thể phục hồi.Lý do lỗi vượt qua đối tượng được ném/Cách xử lý lỗi trong JavaScript hiện đại

Tôi đã sử dụng Java trong nhiều năm và tôi đã quen với một loạt các lớp ngoại lệ.

Nhưng đây là JavaScript. Tôi đoán đó là vấn đề về phong cách. Vấn đề quan trọng của tôi là làm thế nào để vượt qua lý do lỗi để nắm bắt các khối. Tôi đã nghĩ đến việc tạo một trong hai "lớp" Lỗi khác nhau vì các lý do lỗi khác nhau, mỗi lý do đều quan tâm đến từng chi tiết về từng vấn đề hoặc một lớp Lỗi duy nhất có lý do là thuộc tính.

Để tôi cho bạn một ví dụ về xử lý cả hai loại lỗi:

catch(e) { 
    if(e instanceof FirstError) { 
    ... 
    } 
    if(e instanceof SecondError) { 
    ... 
    } 
} 

catch(err) { 
    if(err instanceof AnError) { 
    if(err.detail === 'becauseOfA') { 
     ... 
    } 
    if(err.detail === 'becauseOfB') { 
     ... 
    } 
    } 
    ... 
} 

nào trong những phương pháp tốt hơn? Cả hai sẽ làm việc, nhưng tôi không thích đầu tiên. Nhiều lớp học dường như với tôi như một chi phí khổng lồ.

Edit:
Tôi đồng ý về việc sử dụng callbacks (cũng đã trả lời here):

// One class per error type 
function(err, ast) { 
    if(err) { 
    if(err instanceof FirstError) { 
     ... 
    } 
    if(err instanceof SecondError) { 
     ... 
    } 
    } 
    ... 
} 

// One class for all errors 
function(err, ast) { 
    if(err) { 
    if(err instanceof AnError) { 
     if(err.detail === 'becauseOfA') { 
     ... 
     } 
     if(err.detail === 'becauseOfB') { 
     ... 
     } 
    } 
    ... 
    } 
} 

// No class at all 
function(err, ast) { 
    if(err) { 
    if(err.detail === 'becauseOfA') { 
     ... 
    } 
    if(err.detail === 'becauseOfB') { 
     ... 
    } 
    ... 
    } 
} 

Vấn đề vẫn tồn tại: Tôi có nên thả tất cả các lớp và sử dụng một đối tượng đơn giản mà không cần bất kỳ thừa kế nguyên chủng? Tôi cần truyền thông tin về vấn đề cho trình xử lý lỗi (cho dù bắt hoặc gọi lại).

Tôi muốn giữ chức năng này đồng bộ vì nó nhỏ và nhanh (có, tôi biết rằng một cuộc gọi lại không thực hiện chức năng async). Bản thân AFAIK Node.js ném lỗi trong mã đồng bộ (fs.readFileSync) trong khi truyền các đối tượng lỗi đến các hàm callback trong các hàm không đồng bộ (fs.readFile).

+0

+1 cho việc sử dụng '==='. Tôi thích phiên bản đầu tiên mặc dù tôi không bao giờ sử dụng 'try'-'catch'es trong Javascript. – Kninnug

+0

+1 cho trường hợp. Tôi cũng tự hỏi phương pháp tốt nhất trong js là gì. – lukaleli

+0

Tôi ngạc nhiên rằng, đến từ Java, bạn miễn cưỡng sử dụng nhiều lớp :) Nhưng nó thực sự là dài: 'var ExceptionTypeA = function() {};'? – RandomSeed

Trả lời

1

Tôi nghĩ, cách tiếp cận tốt nhất cho nút là viết lại mô-đun của bạn theo kiểu gọi lại. Mặc dù bạn nên chuyển đến callbacks hai đối số: đầu tiên là lỗi hoặc null (nếu hoạt động hoàn thành thành công), thứ hai là kết quả của phép toán (hoặc null hoặc undefined, nếu xảy ra lỗi).

Hơn bạn chỉ có thể xử lý chúng trong cuộc gọi lại của mình. Bạn có thể truyền lỗi dưới dạng chuỗi, sau đó chỉ là trường hợp (lỗi) để xử lý các tình huống khác nhau.

UPD:

Đối với phương pháp đồng bộ bạn có thể sử dụng ném, nhưng bạn cũng có thể ném chỉ là chuỗi và sau đó chuyển chúng. Nếu bạn muốn đánh máy lỗi (ví dụ, nếu phương pháp có thể ném các lỗi rất khác nhau (trong mã Java chúng có thể được mô tả trong các lớp khác nhau)), bạn có thể sử dụng đối tượng như sau: {error: 'error_name', type: 'error_type '}.

Và sau đó chuyển (err.type), chuyển (err.error).

Sử dụng các lớp học trong Javascript không phải là cách tiếp cận tốt nhất, vì nó đơn giản tạo đối tượng với thuộc tính mẫu, trỏ tới đối tượng hàm tạo và instaceof so sánh con trỏ đó.

+0

Cảm ơn bạn! Vì vậy, tôi sẽ thả tất cả các lớp lỗi và chuyển các vấn đề cho một cuộc gọi lại, phải không? Bản thân node.js có truyền các đối tượng Error (các thể hiện của các lỗi) vào các cuộc gọi lại không? Đây có phải là cách tiếp cận tốt nhất cho một chức năng không đồng bộ không? –

Các vấn đề liên quan