Một ngoại lệ là một lỗi chặn .
Trước hết, cách tốt nhất là không được ném ngoại lệ cho bất kỳ loại lỗi nào, trừ khi đó là lỗi chặn .
Nếu lỗi là chặn , sau đó ném ngoại lệ. Một khi ngoại lệ đã được ném, không cần phải che giấu nó bởi vì nó là ngoại lệ; cho người dùng biết về nó (bạn nên định dạng lại toàn bộ ngoại lệ cho thứ gì đó hữu ích cho người dùng trong UI).
Công việc của bạn là nhà phát triển phần mềm là nỗ lực ngăn chặn một trường hợp đặc biệt trong đó một số tình huống tham số hoặc thời gian chạy có thể kết thúc bằng một ngoại lệ. Đó là, các ngoại lệ không được tắt tiếng, nhưng chúng phải được tránh .
Ví dụ: nếu bạn biết rằng một số đầu vào số nguyên có thể có định dạng không hợp lệ, hãy sử dụng int.TryParse
thay vì int.Parse
. Có rất nhiều trường hợp bạn có thể làm điều này thay vì chỉ nói "nếu thất bại, chỉ cần ném một ngoại lệ".
Ném ngoại lệ là đắt tiền.
Rốt cuộc, nếu một ngoại lệ được ném ra, thay vì viết ngoại lệ vào nhật ký một khi nó đã bị ném, một trong những thực tiễn tốt nhất là bắt nó trong một trình xử lý ngoại lệ cơ hội đầu tiên . Ví dụ:
- ASP.NET: Global.asax Application_Error
- Thứ khác: sự kiện AppDomain.FirstChanceException .
Quan điểm của tôi là các thử / bắt cục bộ phù hợp hơn để xử lý các trường hợp đặc biệt trong đó bạn có thể dịch một ngoại lệ sang một trường hợp khác hoặc khi bạn muốn "tắt tiếng" nó cho một trường hợp rất, rất, rất, rất đặc biệt (một lỗi thư viện ném một ngoại lệ không liên quan mà bạn cần tắt tiếng để khắc phục toàn bộ lỗi).
Đối với phần còn lại của các trường hợp:
- Cố gắng tránh ngoại lệ.
- Nếu điều này là không thể: xử lý ngoại lệ cơ hội đầu tiên.
- Hoặc sử dụng khía cạnh PostSharp (AOP).
Trả lời @thewhiteambit về một số bình luận ...
@thewhiteambit nói:
Ngoại lệ không phải là Lỗi nghiêm trọng, chúng là Ngoại lệ! Đôi khi, chúng thậm chí không phải là Lỗi, nhưng để xem xét chúng là Lỗi nghiêm trọng - Lỗi là sự hiểu biết hoàn toàn sai về Ngoại lệ là gì.
Trước hết, làm thế nào một ngoại lệ thậm chí không thể là một lỗi?
- Không có kết nối cơ sở dữ liệu => ngoại lệ.
- Định dạng chuỗi không hợp lệ để phân tích thành một số loại => ngoại lệ
- Cố gắng phân tích JSON và trong khi đầu vào không thực sự là JSON => ngoại lệ
- Đối số
null
trong khi đối tượng được mong đợi => ngoại lệ
- Một số thư viện có lỗi => ném ngoại lệ không mong muốn
- Có một kết nối ổ cắm và nó bị ngắt kết nối. Sau đó, bạn cố gắng gửi tin nhắn => ngoại lệ
- ...
Chúng tôi có thể liệt kê 1k trường hợp khi một ngoại lệ được đưa ra và sau tất cả, bất kỳ trường hợp nào có thể sẽ là một lỗi .
Một ngoại lệ là một lỗi, bởi vì vào cuối ngày, nó là một đối tượng thu thập thông tin chẩn đoán - nó có một thông báo và nó xảy ra khi có sự cố.
Không ai sẽ ném ngoại lệ khi không có trường hợp ngoại lệ. Các ngoại lệ nên chặn lỗi vì một khi chúng bị ném, nếu bạn không cố gắng sử dụng thử / bắt và ngoại lệ để thực hiện luồng kiểm soát, điều đó có nghĩa là ứng dụng / dịch vụ của bạn sẽ dừng hoạt động được đưa vào một trường hợp đặc biệt .
Ngoài ra, tôi đề nghị mọi người nên kiểm tra mô hình thất bại nhanh chóng được xuất bản bởi Martin Fowler (và được viết bởi Jim Shore) . Đây là cách tôi luôn hiểu cách xử lý các trường hợp ngoại lệ, ngay cả trước khi tôi nhận được tài liệu này một thời gian trước đây.
[...] coi chúng là Tử vong - Lỗi là sự hiểu biết hoàn toàn sai về ngoại lệ là gì.
Thông thường các ngoại lệ cắt giảm một số luồng hoạt động và chúng được xử lý để chuyển đổi chúng thành các lỗi có thể hiểu được của con người. Do đó, có vẻ như một ngoại lệ thực sự là một mô hình tốt hơn để xử lý các trường hợp lỗi và xử lý chúng để tránh sự cố hoàn toàn cho ứng dụng / dịch vụ và thông báo cho người dùng / người tiêu dùng rằng đã xảy ra sự cố.
Thêm câu trả lời về mối quan tâm @thewhiteambit
Ví dụ, trong trường hợp Thiếu kết nối cơ sở dữ liệu, chương trình có thể tiếp tục đặc biệt bằng cách ghi vào tệp cục bộ và gửi các thay đổi tới Cơ sở dữ liệu sau khi có sẵn một lần nữa. Việc truyền chuỗi String-To-Number không hợp lệ của bạn có thể được thử phân tích lại bằng cách diễn giải ngôn ngữ địa phương trên Exception, giống như khi bạn thử ngôn ngữ tiếng Anh mặc định thành Parse ("1,5") và bạn thử lại với phiên dịch tiếng Đức hoàn toàn tốt vì chúng tôi sử dụng dấu phẩy thay vì điểm như dấu phân cách. Bạn thấy các Ngoại lệ này thậm chí không được chặn, chúng chỉ cần xử lý Ngoại lệ.
Nếu ứng dụng của bạn có thể hoạt động ngoại tuyến mà không lưu dữ liệu vào cơ sở dữ liệu, bạn không nên sử dụng ngoại lệ , vì việc triển khai luồng kiểm soát sử dụng try/catch
được coi là một mô hình chống. Công việc ngoại tuyến là trường hợp sử dụng có thể, vì vậy bạn triển khai luồng kiểm soát để kiểm tra xem cơ sở dữ liệu có thể truy cập được hay không, bạn không đợi cho đến khi không thể truy cập được .
Điều phân tích cú pháp cũng là một trường hợp dự kiến ( không phải TRƯỜNG HỢP TUYỆT VỜI ). Nếu bạn mong đợi điều này, bạn không sử dụng ngoại lệ để thực hiện kiểm soát luồng! . Bạn nhận được một số siêu dữ liệu từ người dùng để biết văn hóa của anh ấy / cô ấy và bạn sử dụng trình định dạng cho việc này! .NET cũng hỗ trợ môi trường này và các môi trường khác, và một ngoại lệ vì phải tránh định dạng số nếu bạn mong muốn sử dụng ứng dụng / dịch vụ cụ thể theo văn hóa của bạn .
Một ngoại lệ chưa được xử lý thường trở thành một Lỗi, nhưng bản thân Ngoại lệ không phải là codeproject.com/Articles/15921/Not- ALL-Exceptions-Are-Errors
Bài viết này chỉ là một ý kiến hoặc quan điểm của tác giả.
Vì Wikipedia cũng có thể chỉ là ý kiến của tác giả phát âm, tôi sẽ không nói đó là giáo điều , nhưng hãy kiểm tra Mã hóa bằng bài báo ngoại lệ nói ở đâu đó trong đoạn nào đó:
[...] Sử dụng các ngoại lệ này để xử lý các lỗi cụ thể phát sinh để tiếp tục chương trình được gọi là mã hóa bằng ngoại lệ. Mô hình chống này có thể nhanh chóng làm giảm phần mềm về hiệu suất và khả năng bảo trì.
Nó cũng nói ở đâu đó:
Sử dụng ngoại lệ không chính xác
Thông thường mã hóa bằng ngoại lệ có thể dẫn đến các vấn đề tiếp theo trong phần mềm với việc sử dụng ngoại lệ không chính xác. Ngoài việc sử dụng xử lý ngoại lệ cho một vấn đề duy nhất, việc sử dụng ngoại lệ không chính xác còn làm điều này thêm bằng cách thực thi mã ngay cả sau khi ngoại lệ được đưa ra. Phương pháp lập trình kém này giống với phương pháp goto trong nhiều ngôn ngữ phần mềm nhưng chỉ xảy ra sau khi phát hiện sự cố trong phần mềm.
Thành thật mà nói, tôi tin rằng phần mềm không thể được phát triển không coi trọng các trường hợp sử dụng. Nếu bạn biết rằng ...
- Cơ sở dữ liệu của bạn có thể ngoại tuyến ...
- Một số tập tin có thể bị khóa ...
- Một số định dạng có thể không được hỗ trợ ...
- Một số xác thực tên miền có thể thất bại ...
- Ứng dụng của bạn sẽ hoạt động ở chế độ ngoại tuyến ...
- bất cứ trường hợp sử dụng nào ...
... bạn sẽ không sử dụng ngoại lệ cho điều đó . Bạn sẽ hỗ trợ các trường hợp sử dụng này bằng cách sử dụng luồng điều khiển thường xuyên.
Và nếu một số trường hợp sử dụng không mong muốn không được bảo vệ, mã của bạn sẽ thất bại nhanh chóng, bởi vì nó sẽ đưa ra một ngoại lệ . Phải, bởi vì một ngoại lệ là một trường hợp đặc biệt .
Mặt khác, và cuối cùng, đôi khi bạn bao gồm các trường hợp ngoại lệ , ném ra các ngoại lệ dự kiến , nhưng bạn không ném chúng để thực hiện luồng kiểm soát. Bạn làm điều đó bởi vì bạn muốn thông báo cho các lớp trên rằng bạn không hỗ trợ một số trường hợp sử dụng hoặc mã của bạn không hoạt động với một số đối số hoặc dữ liệu / thuộc tính môi trường nhất định.