Các thực tiễn tốt nhất để xử lý lỗi JavaScript là gì?


137

Tôi đang tìm cách để bắt đầu thực hiện hoạt Javascript hơn một chút bằng chứng lỗi của tôi, và tôi đang tìm rất nhiều tài liệu về việc sử dụng try, catch, finally, và throw, nhưng tôi không tìm thấy một tấn của lời khuyên từ các chuyên gia về khi nào và nơi để ném lỗi.

  • Mỗi đoạn mã có nên được bọc trong một lần thử / bắt không?
  • Có lời khuyên nào như thế này vào thời điểm nào nên bắt lỗi không?
  • Có bất lợi cho việc tăng lỗi thay vì có mã thất bại trong sản xuất không?
  • Điều này đã được chạm đến trên SO cho đến khi triển khai, nhưng các lỗi đăng nhập máy chủ có phải là một chiến lược hiệu quả không?
  • Bất cứ điều gì khác tôi nên biết, liên quan đến lỗi bẫy trong ứng dụng của tôi?

Tôi cũng hoàn toàn chơi trò chơi để nghe những cuốn sách có chương hay giải thích sâu sắc về xử lý lỗi. JavaScript hiệu quả chạm vào vấn đề, nhưng không quá nguyên tắc hoặc có ý kiến ​​về vấn đề này.

Cảm ơn cho bất kỳ lời khuyên bạn có thể cung cấp!


Nó chắc chắn phụ thuộc vào mức độ thất bại ngoạn mục của bạn nếu có sự cố xảy ra và khối lượng thông báo lỗi có thể xảy ra. Bạn không muốn thất bại vì thư mục đăng nhập lỗi của bạn đã đầy đủ phải không? - Bạn đã nhìn vào đây chưa? stackoverflow.com/search?q=error+logging+javascript
mplungjan

@mplungjan - Tôi đã quét qua các câu trả lời ở đó, nhưng dường như không có nhiều quy tắc và các tìm kiếm xử lý lỗi Javascript / thực tiễn tốt nhất ngoại lệ không có gì, vì vậy tôi nghĩ có thể hữu ích để thử và thu hút một số suy nghĩ cô đọng, cho cả tôi sự hiểu biết của riêng mình và những người tìm kiếm trong tương lai. Có lẽ đây là một chủ đề trong đó quy định các thực tiễn tốt nhất là không thể, nhưng mỗi tình huống đều rất độc đáo?
Joshua Cody

1
"Mỗi đoạn mã có nên được bọc trong một lần thử / bắt không?" Dĩ nhiên là không. Có rất nhiều mã mà bạn biết sẽ luôn hoạt động (tất nhiên, giả sử bạn đã kiểm tra nó, nhưng điểm thử / bắt không phải là bắt hoặc che giấu lỗi mã hóa). Chỉ gói mã có thể bị lỗi đôi khi do điều gì đó nằm ngoài sự kiểm soát của nó, nói chung là những thứ như truy cập tài nguyên, v.v ... Lưu ý: một số điều không thể xử lý lỗi tích hợp, ví dụ: tôi sẽ không bận tâm mã hóa Ajax từ đầu có rất nhiều thư viện thực hiện việc xử lý các sự cố trên trình duyệt và cho phép bạn chỉ định chức năng xử lý lỗi.
nnnnnn

1
Đây là một câu hỏi hay Josh, +1. Rất nhiều lời khuyên cú pháp xung quanh, nhưng như bạn nói đó là phần dễ dàng. Nó được đưa ra trong câu trả lời của câu hỏi này ( stackoverflow.com/questions/2825427/ Khăn ) trong đó giải thích rằng Ngoại lệ không được sử dụng phổ biến trong JS và lý do được đưa ra.
whitneyland

Câu trả lời:


63

Có thể tìm thấy một bộ slide cực kỳ thú vị về Xử lý lỗi JavaScript doanh nghiệp tại địa chỉ http://www.devhands.com/2008/10/javascript-error-handling-and-general-best-practices/

Tóm lại, nó tóm tắt:

  1. Giả sử mã của bạn sẽ thất bại
  2. Đăng nhập lỗi vào máy chủ
  3. Bạn, không phải trình duyệt, xử lý lỗi
  4. Xác định nơi có thể xảy ra lỗi
  5. Ném lỗi của riêng bạn
  6. Phân biệt các lỗi nghiêm trọng và không gây tử vong
  7. Cung cấp chế độ gỡ lỗi

Các slide đi vào chi tiết hơn nhiều và có lẽ sẽ cung cấp cho bạn một số hướng.

CẬP NHẬT

Bài thuyết trình được đề cập ở trên có thể được tìm thấy ở đây: http://www.sl slideshoware.net/nzakas/enterprise-javascript-error-handling-presentation


24
Liên kết devhands bị hỏng.
Ryan Gates

7
Đối với những người đọc điều này trong năm 2017, tôi cho rằng bạn sẽ không nhận được nhiều giá trị từ các slide - tóm tắt này cung cấp cho bạn 90% thông tin. Nó vẫn là thông tin có giá trị. Chúc mừng!
Philippe Hebert

29

Nicholas Zakas của Yahoo! sự nổi tiếng đã nói về Xử lý lỗi doanh nghiệp ( slide ) tại Ajax Experience 2008, trong đó anh ấy đã đề xuất một cái gì đó như thế này:

function log(sev,msg) {
    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

// usage
log(1, "Something bad happened.")

// Auto-log uncaught JS errors
window.onerror = function(msg, url, line) {
    log(1, msg);
    return true;
}

Một năm sau, Nicholas Zakas đã đăng một bản cập nhật trên blog của mình , trong đó có một mẫu thông minh để tự động xử lý mã xử lý lỗi trên môi trường sản xuất của bạn (sử dụng lập trình hướng theo khía cạnh).

Khi bạn bắt đầu đăng nhập các cuộc gọi window.error, bạn sẽ nhận thấy hai điều:

  1. Nếu trang web của bạn khá phức tạp, bạn sẽ đăng nhập rất nhiều lỗi
  2. Bạn sẽ thấy một loạt các "window.error" vô dụng trong các tin nhắn không xác định: 0 "

Giảm torrent của các mục nhật ký cũng đơn giản như kiểm tra mức độ nghiêm trọng và / hoặc một số ngẫu nhiên trước khi đăng nhập vào máy chủ:

function log(sev,msg) {
    if (Math.random() > 0.1) return; // only log some errors

    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

Xử lý các lỗi "window.error vô dụng: 0" không xác định tùy thuộc vào kiến ​​trúc trang web của bạn, nhưng có thể thử xác định tất cả các cuộc gọi Ajax và ném ngoại lệ khi có lỗi (có thể trả về dấu vết ngăn xếp bằng stacktrace.js ).


67
Tôi biết đây là một câu hỏi cũ, nhưng đề nghị bỏ qua ngẫu nhiên một số lỗi là một trong những ý tưởng tồi tệ nhất tôi từng nghe.
jbabey

26
@jbabey: Đối với một trang web nhỏ, bạn đã đúng, nhưng nếu bạn đang điều hành một trang web lớn với 100.000 hoặc hàng triệu người dùng, bạn thực sự không cần phải làm ngập máy chủ của mình (hoặc internet) với các yêu cầu đăng nhập dự phòng. Trên một hệ thống đủ lớn, mọi lỗi thực sự sẽ xảy ra hàng chục ngàn lần một ngày, vì vậy hình thức giới hạn này hoạt động tốt. Ý tưởng được thực hiện tại Facebook.
Jens Roland

1
Ghi nhật ký lỗi trong khi ở chế độ gỡ lỗi có thể cũng quan trọng như việc giới hạn các báo cáo lỗi sản xuất, vì vậy người ta có thể lưu ý rằng cần có giải pháp để quản lý giá trị đó giới hạn ngưỡng ghi nhật ký.
frattaro

2
@NickBull Tôi đã thiết kế lại một loạt các mô-đun JavaScript của Facebook vào năm 2011-2012; đó là nơi tôi tìm thấy nó
Jens Roland

1
@NickBull vừa kiểm tra các tập tin cũ của tôi, vẫn còn những thứ này. Tôi đã tìm thấy mẹo này trong mô-đun bộ tải khởi động của Facebook: if (global.logJSError) if (Math.random() < .01) logJSError('bootloader', {(phải thừa nhận rằng mã không tiết kiệm tất cả các lỗi, chỉ có một loại lỗi hết thời gian cụ thể)
Jens Roland

7

IHMO, bạn nên sử dụng xử lý lỗi trong javascript giống như bạn làm trong một số ngôn ngữ khác (AFAIK: Python, Java).

Để dễ đọc hơn (và có thể hiệu suất tốt hơn, mặc dù tôi không chắc nó có tác động thực sự lớn), bạn nên sử dụng khối thử / bắt chủ yếu trong các trường hợp sau:

  • Phần mã bạn muốn bọc là một phần quan trọng của toàn bộ thuật toán . Nếu thất bại, nó có thể:

    • tạo lỗi trên phần tiếp theo của mã (ví dụ: vì thiếu var ...)
    • làm cho trang không trông như mong đợi (tác động đến nội dung hoặc css)
    • làm cho kết quả xuất hiện lạ đối với người dùng (tác động đến hành vi mã)
  • Bạn biết rằng mã bạn đang viết không tương thích với mọi trình duyệt

  • Bạn đã lên kế hoạch rằng mã có thể thất bại (vì không có cách nào khác để kiểm tra xem nó có hoạt động không nếu ... thì ... khối)
  • Và cũng khi bạn muốn gỡ lỗi mà không làm phiền người dùng cuối cùng

Cuối cùng, các chuyên gia javascript có thể có các yếu tố khác để cung cấp.

2 xu của tôi vào hộp,

Trân trọng,

Tối đa


1
"Phần mã bạn muốn bọc là một phần quan trọng của toàn bộ thuật toán" - có thể phụ thuộc vào cách bạn muốn xử lý lỗi. Nếu bạn biết không có cách nào để tiếp tục với thuật toán khi thất bại, tốt hơn hết là nên bọc toàn bộ trong một lần thử / bắt bởi vì nếu lần thử / bắt của bạn là (ví dụ) bị chôn vùi bên trong các vòng lặp lồng nhau, thì đó sẽ là một cú đánh hiệu suất . Mặt khác, nếu bạn có thể thực hiện một số hành động ngoại lệ và tiếp tục với thuật toán thì bạn sẽ cần một thiết lập thử / bắt chi tiết hơn.
nnnnnn

5

Ngoài các câu trả lời khác: một điều quan trọng là sử dụng dữ liệu ngữ cảnh có sẵn trong các đối tượng lỗi JavaScript và trong các window.onerrortham số hàm.

Những thứ như stacktrace (errorObject.stack), tên tệp, số dòng và số cột. Lưu ý rằng mỗi trình duyệt có một số khác biệt ... vì vậy hãy nỗ lực hết sức để có được những lỗi hay.

Thậm chí có thể có vấn đề với chính đối tượng console . Tôi sử dụng một hàm window.onerror tùy chỉnh được lấy cảm hứng từ cái này và một hàm đặc biệt để theo dõi bất kỳ đối tượng lỗi tiêu chuẩn nào được lấy cảm hứng từ mã này .

Một điểm tốt khác là bao gồm phiên bản của ứng dụng web của bạn ở đâu đó gần với stacktrace (để sao chép và dán nhanh chóng và an toàn). Bạn cũng có thể hiển thị lỗi mạnh hơn (cảnh báo ...) trong chế độ phát triển vì nhà phát triển sẽ không liên tục theo dõi bảng điều khiển trình duyệt và có thể không thấy một số vấn đề.

Cũng sử dụng tránh sử dụng throw 'My message', sử dụng throw new Error('My message'), bạn thậm chí có thể có lỗi tùy chỉnh, đọc bài viết này .

Luôn thêm một số ngữ cảnh cho các lỗi (phiên bản, id của đối tượng, một số thông báo tùy chỉnh, ...) và cũng đảm bảo bạn phân biệt giữa các lỗi bên ngoài (một số dữ liệu hoặc tình huống bên ngoài khiến hệ thống của bạn bị lỗi) và lỗi bên trong / xác nhận (hệ thống của bạn bị rối tung), đọc về ' Thiết kế theo hợp đồng '.

Đây là một hướng dẫn .

Ngoài ra, hãy suy nghĩ về việc sử dụng xử lý lỗi chung như chặn các lib và khung của bạn:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.