Cách triển khai Xử lý lỗi [đã đóng]


13

Mặc dù tôi đã lập trình ở cấp độ chuyên nghiệp trong một số năm, tôi vẫn không hiểu đầy đủ về xử lý lỗi. Mặc dù các ứng dụng của tôi hoạt động tốt, nhưng việc xử lý lỗi không được triển khai ở cấp độ chuyên nghiệp và là sự pha trộn và kết hợp của một số kỹ thuật.

Không có cấu trúc đằng sau xử lý lỗi của tôi. Tôi muốn tìm hiểu và hiểu cách thức triển khai ở cấp độ chuyên nghiệp. Đây là một lĩnh vực mà tôi thiếu kiến ​​thức.

Khi nào tôi nên sử dụng một ngoại lệ và khi nào tôi nên trả lại trạng thái thành công, để được kiểm tra trong luồng logic? Có thể trộn ngoại lệ và trả lại trạng thái không?

Tôi mã trong C # là chủ yếu.


2
Tại sao lại bỏ phiếu? Tôi đang hỏi một câu hỏi nghiêm túc về việc thực hiện xử lý lỗi và cách thực hiện. Nếu đây không phải là nơi tốt nhất để đặt câu hỏi như vậy trong số các lập trình viên thì ở đâu? Nó thực sự làm tôi bực mình khi mọi người bình chọn những câu hỏi như vậy bởi vì không có nơi nào khác để hỏi một câu hỏi như vậy. Đây có thể là nơi duy nhất trên web nơi tôi sẽ nhận được câu trả lời đáng tin cậy và các tài nguyên có thể. Vì vậy, thay vì bỏ phiếu một câu hỏi mà người khác chắc chắn Google sẽ không dễ trả lời hơn?
James Jeffery

6
Câu hỏi của bạn rất rộng. Có lẽ bạn có thể thu hẹp phạm vi bằng cách liên quan đến các ví dụ cụ thể về cách bạn đã không đạt được mục tiêu mã hóa của mình.
Andyz Smith

Có rất nhiều bài viết trên web về xử lý lỗi: Hãy thử điều này: msdn.microsoft.com/en-us/l Library /seyhszts.aspx
Nir Kornfeld

Câu trả lời:


25
  1. Sử dụng ngoại lệ cho những điều đặc biệt, những điều bạn không thể mong đợi gặp phải quá thường xuyên, những điều chỉ ra rằng có điều gì đó không ổn. Ví dụ, nếu mạng ngừng hoạt động, đó là một điều đặc biệt đối với máy chủ web. Nếu cơ sở dữ liệu không có sẵn, điều đó có nghĩa là có gì đó không đúng. Nếu tập tin cấu hình bị thiếu, có lẽ điều đó có nghĩa là người dùng đã nhầm lẫn với nó.

  2. Đừng sử dụng ngoại lệ để xử lý mã không chính xác. Để kiểm tra tính chính xác của mã, bạn nên sử dụng các xác nhận hoặc trong .NET Framework 4 trở lên, các hợp đồng Mã (thay thế các xác nhận và có các tính năng bổ sung, đặc biệt có giá trị).

  3. Đừng sử dụng ngoại lệ trong các trường hợp không đặc biệt. Việc người dùng, khi được yêu cầu nhập số, nhập "chó" không phải là ngoại lệ để xứng đáng là một ngoại lệ.

  4. Hãy cẩn thận khi chọn các loại ngoại lệ. Tạo các loại của riêng bạn khi cần thiết. Cẩn thận chọn gia tài, hãy nhớ rằng bắt cha mẹ cũng sẽ bắt được con. Không bao giờ throw Exception.

  5. Không sử dụng mã trả lại cho các lỗi. Mã lỗi dễ bị che, bị bỏ qua, bị lãng quên. Nếu có lỗi, hãy xử lý nó hoặc truyền nó đến ngăn xếp phía trên.

  6. Trong trường hợp một phương thức được dự kiến ​​sẽ trả về lỗi và lỗi không phải là ngoại lệ, hãy sử dụng enums, không bao giờ lỗi số. Thí dụ:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    Ý nghĩa của LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErrorv.v. rõ ràng hơn nhiều so với việc nhớ rằng mã 12 có nghĩa là máy chủ ngừng hoạt động và mã 13 - rằng dữ liệu không thể được phân tích cú pháp.

  7. Sử dụng mã lỗi khi chúng đề cập đến các mã phổ biến, được biết đến bởi mọi nhà phát triển làm việc trong miền cụ thể. Ví dụ: không phát minh lại giá trị enum cho HTTP 404 Không tìm thấy hoặc Lỗi HTTP 500 Internal Server.

  8. Cẩn thận với booleans. Sớm hay muộn, bạn sẽ muốn biết không chỉ một phương pháp cụ thể thành công hay thất bại, mà tại sao. Ngoại lệ và enums mạnh hơn nhiều cho điều đó.

  9. Đừng bắt mọi ngoại lệ (trừ khi bạn ở trên cùng của ngăn xếp). Nếu bạn bắt được một ngoại lệ, bạn nên sẵn sàng xử lý nó. Nắm bắt mọi thứ đang cho thấy rằng bạn không quan tâm nếu mã của bạn chạy chính xác. Điều này có thể giải quyết "Tôi không muốn tìm kiếm ngay cách khắc phục vấn đề này", nhưng sẽ sớm làm tổn thương bạn.

  10. Trong C #, không bao giờ nghĩ lại các ngoại lệ như thế này:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    bởi vì bạn đang phá vỡ ngăn xếp. Thay vào đó, hãy làm điều này:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Hãy nỗ lực khi viết tin nhắn ngoại lệ. Đã bao nhiêu lần tôi nhìn thấy một cái gì đó như throw Exception("wrong data")hoặc throw Exception("shouldn't call this method in this context"). Các nhà phát triển khác, bao gồm chính bạn sáu tháng sau, sẽ không biết dữ liệu nào sai và tại sao hoặc tại sao chúng ta không nên gọi một phương thức nào đó trong ngữ cảnh, cũng không phải bối cảnh chính xác.

  12. Không hiển thị thông báo ngoại lệ cho người dùng. Chúng không được mong đợi cho những người bình thường và thậm chí thường không thể đọc được cho chính các nhà phát triển.

  13. Đừng bản địa hóa các tin nhắn ngoại lệ. Tìm kiếm tài liệu cho một tin nhắn địa phương là mệt mỏi và vô nghĩa: mọi tin nhắn chỉ nên bằng tiếng Anh và tiếng Anh.

  14. Đừng tập trung hoàn toàn vào các ngoại lệ và lỗi: nhật ký cũng cực kỳ quan trọng.

  15. Trong .NET, đừng quên bao gồm các ngoại lệ trong tài liệu XML của phương thức:

    /// <exception cref="MyException">Description of the exception</exception>

    Bao gồm các ngoại lệ trong tài liệu XML giúp mọi người sử dụng thư viện dễ dàng hơn nhiều. Không có gì khó chịu hơn là cố gắng đoán ngoại lệ nào có thể được ném bởi một phương thức và tại sao.

    Theo nghĩa này, xử lý ngoại lệ Java cung cấp một cách tiếp cận chặt chẽ hơn, tốt hơn. Nó buộc bạn phải xử lý các ngoại lệ có khả năng bị ném bởi các phương thức được gọi hoặc khai báo theo phương thức của riêng bạn rằng nó có thể ném các ngoại lệ mà bạn không xử lý, làm cho mọi thứ trở nên đặc biệt minh bạch.


Điều này đang được nói, tôi thấy sự phân biệt Java giữa các ngoại lệ và lỗi khá vô dụng và khó hiểu, vì ngôn ngữ đã được kiểm tra và không được kiểm tra ngoại lệ. May mắn thay, .NET Framework chỉ có ngoại lệ và không có lỗi.


Tôi đã học được trích dẫn một chút từ điều này, tôi có thể hỏi danh sách đến từ đâu không? Trang web hay kinh nghiệm cá nhân? Cả hai cách làm việc đặc biệt (hehe có được không?).
Shelby115

@ Shelby115: danh sách đến từ, theo thứ tự: Trao đổi ngăn xếp, trải nghiệm cá nhân và Hoàn thành mã của Steve Mcconnell.
Arseni Mourzenko

Cảm ơn bạn @MainMa đó là một phản hồi tuyệt vời! Tôi đã từng sở hữu Code Complete khi tôi ở trường Đại học nhưng ai đó đã đánh cắp nó. Tôi đã không được đọc nó.
James Jeffery

@JamesJeffery: sau đó mượn phiên bản thứ hai trong thư viện hoặc mua một cuốn: đó là một trong những cuốn sách hiếm hoi liên quan đến phát triển hoàn toàn đáng đồng tiền bát gạo.
Arseni Mourzenko

@MainMa Chỉ cần đặt hàng từ Amazon, cảm ơn: DI cũng sở hữu Clean Code và hoàn toàn quên mất Chương 7.
James Jeffery

1

Tôi nghĩ rằng danh sách của MainMa rất đầy đủ. Tôi sẽ chỉ thêm một vài thứ của riêng tôi:

  1. Đọc bài viết của Eric Lippert về cách anh ấy phân loại các trường hợp ngoại lệ. Đặc biệt quan trọng là quan điểm của anh ấy về việc không nắm bắt các ngoại lệ trong các lỗi thực tế trong mã của bạn. Sửa mã thay thế!
  2. Nếu bạn biết rằng một ngoại lệ có thể xảy ra VÀ bạn có thể làm gì đó với nó, xử lý nó, nhưng giới hạn phạm vi bạn thử bắt và bắt ngoại lệ cụ thể mà bạn mong đợi. Đó là, đừng làm điều này:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Thay vào đó hãy làm điều này:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • Đừng sử dụng ngoại lệ cho luồng điều khiển. Ví dụ: không ném ClientNotFoundException vào hộp thoại tra cứu (không tìm thấy ứng dụng khách nào là không ngoại lệ trong tình huống này) và mong muốn mã gọi hiển thị thông báo "Không tìm thấy kết quả" khi điều này xảy ra.

  • Đừng nuốt ngoại lệ!

  • Hãy nhớ rằng thực sự xử lý một ngoại lệ chỉ có thể có nghĩa là 3 điều:

    1. Thử lại thao tác. Chỉ có giá trị nếu vấn đề là thoáng qua.
    2. Hãy thử một sự thay thế.
    3. Thông báo cho ai đó về vấn đề. Chỉ có hiệu lực nếu thông báo là hành động, có nghĩa là người dùng có thể làm gì đó về nó.

    Nếu không có tùy chọn nào trong số này áp dụng thì có lẽ bạn không nên bắt ngoại lệ đó. Tuy nhiên, bạn nên đăng nhập nó và sau đó hủy thao tác hoặc tắt. Tất nhiên điều này phụ thuộc vào những yêu cầu của bạn liên quan đến tính đúng đắn và sự mạnh mẽ.

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.