Là hợp lý hơn để ghi lại các ngoại lệ trong một bắt tất cả hoặc trong một lớp ngoại lệ cơ sở?


15

Tôi đang trong quá trình tái cấu trúc một ứng dụng web khá lớn. Một trong những vấn đề chính là xử lý lỗi không nhất quán và tôi đang cố gắng đưa ra một chiến lược hợp lý. Tôi đã tạo một trình xử lý lỗi tùy chỉnh, thông qua set_error_handler về cơ bản biến các lỗi PHP trong ErrorExceptions và một lớp ngoại lệ cơ sở tùy chỉnh, trực tiếp kế thừa từ Ngoại lệ .

Khi sản xuất, tôi đang sử dụng một ngoại lệ chung bắt tất cả, thông qua set_exception_handler và tôi sắp thêm ghi nhật ký ngoại lệ * vào hỗn hợp. Vấn đề nan giải của tôi là nơi thực hiện ghi nhật ký thực tế, trong lớp ngoại lệ cơ sở hoặc trong tất cả.

Tôi đã nghĩ ra một vài lý do để đăng nhập nó trong tất cả:

  • Có khá nhiều trường hợp ngoại lệ trong mã cần được chuyển đổi thành một số phần tử con thích hợp của lớp ngoại lệ cơ sở. Cho đến khi điều đó xảy ra, không phải tất cả các ngoại lệ sẽ được đăng nhập.
  • Bằng cách nào đó cảm thấy tự nhiên hơn để làm điều đó trong tất cả, một lớp ngoại lệ cơ sở không nên làm nhiều hơn là chỉ như vậy. (Nó có thể là một nguyên tắc trách nhiệm duy nhất, nhưng nó chỉ có thể là một cảm giác sai lầm)

và một lý do để đăng nhập vào lớp ngoại lệ cơ sở:

  • Hiện tại, tất cả chỉ được sử dụng trong sản xuất. Có thể dễ dàng giới thiệu nó trên các môi trường khác của chúng tôi (phát triển, thử nghiệm) nhưng điều đó sẽ yêu cầu một vài điều chỉnh, vì các lỗi được xử lý khác nhau trên mỗi môi trường, như trên sản xuất, chúng được dịch sang các trang lỗi 404/503.

Có bất kỳ thực hành chấp nhận được cho nơi đăng nhập ngoại lệ?

* Ghi nhật ký sẽ liên quan đến việc ghi vào tệp văn bản lúc đầu và có thể phát triển thành gửi thư cho một số loại ngoại lệ nhất định.


Một số làm rõ, được nhắc nhở bởi câu trả lời của @ unsolysampler's :

Tôi đang đối mặt với một cơ sở mã hóa 2 * 10 ^ 6, với rất nhiều nội dung của bên thứ ba mà tôi không kiểm soát được và một số mã tôi có quyền kiểm soát các ngoại lệ trước ngày trong PHP. Và cũng có một số mã gần đây tào lao, chúng tôi đang phục hồi sau một thời gian dài áp lực mạnh mẽ, nơi chúng tôi hầu như phải ngừng suy nghĩ và chỉ bị hack.

Chúng tôi đang tích cực tái cấu trúc để giải quyết tất cả các mâu thuẫn và đưa ra cách tiếp cận xử lý lỗi hợp lý, nhưng điều đó sẽ mất một thời gian. Tôi quan tâm nhiều hơn đến những việc cần làm cho đến khi tôi đạt đến điểm xử lý lỗi một cách thích hợp. Có thể tôi sẽ hỏi một câu hỏi khác về một chiến lược ngoại lệ hợp lý tại một số điểm.

Động lực chính của việc đăng nhập là nhận email trên điện thoại của tôi mỗi khi có điều gì đó không hay xảy ra trong quá trình sản xuất. Tôi không quan tâm nếu các bãi chứa dữ liệu trở nên to lớn, nếu chúng làm tôi sẽ có một công việc định kỳ xóa những cái cũ mọi lúc.

Câu trả lời:


11

Nói tóm lại, lần duy nhất bạn nên ghi lại sự tồn tại của một ngoại lệ là khi bạn đang xử lý nó.

Khi bạn ném một ngoại lệ, đó là do mã của bạn đã đạt đến trạng thái không thể tiến hành chính xác. Bằng cách ném một ngoại lệ, bạn đang thể hiện một thông báo cụ thể cho chương trình của bạn về lỗi xảy ra. Bạn không nên bắt một ngoại lệ cho đến khi bạn đang ở một điểm mà nó có thể được xử lý đúng cách.

Mã bạn viết như một phần của ứng dụng chính của bạn nên biết về các loại ngoại lệ có thể được ném và khi nào chúng có thể bị ném. Nếu bạn không thể làm bất cứ điều gì có ích với một ngoại lệ, đừng bắt nó. Không đăng nhập một ngoại lệ cho đến khi nó được xử lý. Chỉ có mã xử lý biết ý nghĩa của ngoại lệ trong ngữ cảnh của luồng chương trình và cách đáp ứng với nó. Viết một thông điệp tường trình ở đây có thể có ý nghĩa ở đây. Nếu bạn sử dụng khung ghi nhật ký, bạn có thể đặt mức ghi nhật ký cho tin nhắn và có khả năng lọc chúng. Điều này hoạt động tốt cho các trường hợp ngoại lệ có thể xảy ra, nhưng không quan trọng và có thể được phục hồi từ sạch.

Ngoại lệ của bạn là tất cả, là nỗ lực cuối cùng của bạn để giữ mã của bạn khỏi một cái chết xấu xí. Nếu bạn đã đạt được điều này, bạn đăng nhập tất cả các thông tin trạng thái và lỗi bạn có thể. Sau đó, bạn làm hết sức mình để nói với người dùng rằng chương trình đang bị sập trước khi mọi thứ dừng lại. Mục tiêu của bạn là không bao giờ có mã này được thực thi.

Nhúng đăng nhập vào lớp cơ sở không tuân theo các nguyên tắc trên. Lớp cơ sở không biết gì về trạng thái của mã. (Có dấu vết ngăn xếp không được tính vì bạn sẽ không viết mã đưa ra quyết định dựa trên phân tích cú pháp.) Lớp cơ sở không thể làm gì để chỉ ra mức độ nghiêm trọng hoặc cách xử lý ngoại lệ. Bạn không muốn các bãi dữ liệu khổng lồ và ngăn xếp dấu vết mỗi khi có một ngoại lệ đơn giản là bạn có thể xử lý và phục hồi sạch sẽ.


Tôi đã thêm một số làm rõ về câu hỏi được nhắc bởi câu trả lời của bạn. Từ những gì tôi thu thập được, về mặt thực tế của câu hỏi bạn đề xuất để đăng nhập vào tất cả?
yannis

1
@YannisRizos: Có, bạn nên thực hiện bắt tất cả như bước đầu tiên của mình. Những gì tôi đã nói về sản phẩm khai thác là nhiều hơn để đảm bảo rằng bạn không sử dụng nó như một phần bình thường trong dòng mã của mình. Việc thực hiện một trình xử lý ngoại lệ chưa được xử lý là rất quan trọng vì nó cho phép bạn nhận được nhiều thông tin mỗi khi mã của bạn làm điều gì đó xấu.
unolysampler

Không có khung ghi nhật ký nào có thể xử lý thuận tiện khái niệm "Đây là một loạt các thứ sẽ được ghi lại trừ khi nó được thay thế"? Mỗi lớp nhìn thấy một ngoại lệ có thể thay thế dữ liệu từ trước đó, ngoại trừ nếu một ngoại lệ mới được đưa ra trong quá trình ngăn xếp, báo cáo nhật ký cuối cùng sẽ không được thay thế và do đó sẽ được ghi lại. Không có khung hỗ trợ một mô hình như vậy?
supercat

3

Nếu ngôn ngữ / thời gian chạy của bạn không dễ dàng cho phép bạn xác định nguồn gốc của ngoại lệ, sẽ có trường hợp đăng nhập nó ngay lập tức. C ++ và một số công cụ JS không hiển thị tệp + đường dây hoặc ngăn xếp cuộc gọi của ngoại lệ vào thời điểm bạn bắt được nó / nhưng thông tin này có sẵn tại thời điểm bạn tạo ngoại lệ.

Giải pháp của chúng tôi là cung cấp một cơ chế sử dụng cấu hình thời gian chạy để cho phép ghi nhật ký loại ngoại lệ cùng với ngăn xếp giá rẻ khi cố gắng chẩn đoán các sự cố này.


+1 Đó chắc chắn là một trường hợp tốt để đăng nhập vào lúc ném ... PHP thực sự cung cấp một dấu vết ngăn xếp đầy đủ khi bắt, vì vậy tôi có thể đi theo một cách khác ...
yannis
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.