2009-03-05 35 views
9

Gần đây tôi đã phát triển một mô-đun bổ sung cho một dịch vụ hiện có được phát triển bởi một đồng nghiệp. Ông đã đặt một khối try/catch trong hàm làm việc chính để bắt tất cả các trường hợp ngoại lệ unhadled rằng bọt lên đến mức này, đăng nhập chúng lại với nhau với thông tin stack trace vv:Cách triển khai xử lý ngoại lệ cấp cao nhất?

try 
{ 
    // do main work 
} 
catch(Exception ex) 
{ 
    // log exception info 
} 

Trong khi điều này làm cho chương trình rất ổn định (như trong 'không sụp đổ'), tôi ghét nó vì khi tôi kiểm tra mã của mình, tôi không thấy các ngoại lệ do nó gây ra. Tất nhiên tôi có thể xem nhật ký ngoại lệ và xem có mục mới hay không, nhưng tôi rất thích phản hồi trực tiếp về ngoại lệ khi nó được ném (với con trỏ trên dòng bên phải trong mã, xin vui lòng).

Tôi đã loại bỏ cấp độ cao nhất này/thử/nắm bắt ít nhất trong khi tôi vẫn đang viết mã và thử nghiệm. Nhưng bây giờ nhiệm vụ của tôi đã hoàn thành và tôi phải quyết định thời gian để đưa nó trở lại cho bản phát hành, hay không. Tôi nghĩ rằng tôi nên làm điều đó, bởi vì nó làm cho dịch vụ ổn định hơn, và toàn bộ quan điểm của nó là nó chạy trong nền mà không cần bất kỳ sự giám sát nào. Mặt khác, tôi đã đọc rằng người ta chỉ nên gọi các trường hợp ngoại lệ cụ thể (như trong IoException), không phải là chung Exception.

Lời khuyên của bạn về vấn đề này là gì?

Nhân tiện, dự án được viết bằng C#, nhưng tôi cũng quan tâm đến câu trả lời cho các ngôn ngữ không phải .NET.

+0

Xem thêm http://stackoverflow.com/questions/576532/is-dying-is-awesome-preferred – Brian

Trả lời

10

Đặt lại.

Ngoại lệ chỉ nên có liên quan trong khi thử nghiệm. Nếu không nó không có ý nghĩa pop nó cho người dùng.

Ghi nhật ký là tốt.

Bạn cũng có thể sử dụng biểu tượng DEBUG do Visual Studio xác định để gỡ lỗi xây dựng dưới dạng cờ.

... 
    } catch(Exception e) { 
#if DEBUG 
      throw; 
#else 
      log as usual 
#endif 
    } 

Vì vậy, lần sửa đổi tiếp theo cần phải đặt cờ gỡ lỗi thành true và ngoại lệ sẽ bật lên.

+0

Hm, tôi thích cờ gỡ lỗi! – Treb

+0

Không nên dùng 'ném' không 'ném e'? Nếu không, theo dõi ngăn xếp được xóa (hoặc một cái gì đó - không quá chắc chắn). – strager

+0

@strager: Yup! Ví dụ trên sẽ che giấu ngoại lệ ban đầu. Chỉ cần sử dụng 'ném'. –

2

Lý tưởng nhất là bạn muốn xử lý ngoại lệ càng gần nơi nó xảy ra càng tốt nhưng điều đó không có nghĩa là một trình xử lý ngoại lệ toàn cầu là một ý tưởng tồi. Đặc biệt là đối với một dịch vụ mà vẫn phải chạy bằng mọi giá. Tôi sẽ tiếp tục những gì bạn đã làm. Vô hiệu hóa nó trong khi gỡ lỗi nhưng để nó ở vị trí để sản xuất.

Hãy nhớ rằng nó nên được sử dụng như một mạng lưới an toàn. Vẫn cố gắng nắm bắt tất cả các trường hợp ngoại lệ trước khi chúng nâng lên xa.

4

Trong bất kỳ ứng dụng Java, bạn chỉ là về luôn muốn xác định một trình xử lý ngoại lệ cho trường hợp ngoại lệ còn tự do với một cái gì đó như thế này:

Thread.setDefaultUncaughtExceptionHandler(...); 

nơi đối tượng đó sẽ nắm bắt những trường hợp ngoại lệ còn tự do sẽ ít nhất là đăng nhập thất bại nên bạn có cơ hội để biết về nó. Nếu không, không có gì đảm bảo rằng bạn thậm chí sẽ được thông báo rằng một Thread đã lấy một Exception - trừ khi đó là Thread chính của bạn. Ngoài việc làm điều này, hầu hết các chủ đề của tôi có một try/catch nơi tôi sẽ bắt RunnableException (nhưng không Error) và đăng nhập nó ... một số Chủ đề sẽ chết khi điều này xảy ra, những người khác sẽ đăng nhập và bỏ qua, những người khác sẽ hiển thị khiếu nại cho người dùng và cho phép người dùng quyết định, tùy thuộc vào nhu cầu của Ứng dụng.Thử/nắm bắt này ở chính gốc của Chủ đề, theo phương pháp Runnable.run() hoặc tương đương. Vì try/catch nằm ở gốc của Thread, đôi khi không cần phải vô hiệu hóa bắt này.

Khi tôi viết bằng C#, tôi viết mã tương tự. Nhưng tất cả điều này phụ thuộc vào nhu cầu của ứng dụng. Là một ngoại lệ mà sẽ làm hỏng dữ liệu? Vậy thì, đừng bắt và bỏ qua nó. LUÔN LUÔN đăng nhập nó, nhưng sau đó Hãy để ứng dụng chết. Tuy nhiên, hầu hết các ngoại lệ không thuộc loại này.

2

Yêu cầu bắt tất cả các ngoại lệ và làm cho chương trình 'ổn định' là rất mạnh và ý tưởng dường như thực sự hấp dẫn đối với mọi người. Vấn đề như bạn chỉ ra là đây chỉ là một mưu mẹo và chương trình rất có thể là lỗi và tồi tệ hơn, w/o chỉ dẫn của thất bại. Không ai giám sát các nhật ký thường xuyên.
Lời khuyên của tôi sẽ là cố gắng thuyết phục nhà phát triển khác thực hiện thử nghiệm rộng rãi và sau đó triển khai nó trong quá trình sản xuất.

+0

Tôi hiểu bạn đến từ đâu, nhưng có một loại ngoại lệ tuyệt vời mà chương trình của bạn có thể chạy ở trạng thái bị suy thoái, nhưng vẫn chạy, nơi bạn thực sự muốn ngoại lệ bắt-và-đăng nhập. Tính ổn định không quan trọng. Bạn chỉ cần biết nơi bạn KHÔNG THỂ làm điều này. – Eddie

+0

@Eddie - True, khu vực này luôn luôn là rất nhiều ứng dụng và người dùng mong đợi phụ thuộc. Tất cả chúng ta đều muốn làm cho các ứng dụng thực hiện mạnh mẽ mà không bao giờ thất bại nhưng sau đó gọi thực tế :). Không có gì đánh bại thử nghiệm trả trước rộng rãi, bảo hiểm mã và đặt cược với khách hàng thực sự để có được sự tự tin. –

1

Nếu bạn muốn xem ngoại lệ khi nó xảy ra, trong Visual Studio, bạn có thể đi tới trình đơn DEBUG, chọn EXCEPTIONS và bạn có thể yêu cầu trình gỡ lỗi ngắt ngay khi ngoại lệ được ném. Bạn thậm chí có thể chọn loại ngoại lệ nào. :)

+0

Và cách thức hoạt động khi chương trình được đề cập đang chạy dưới dạng SERVICE? – Treb

+2

Nếu bạn tải dịch vụ vào bộ nhớ, sau đó đính kèm vào nó, tất cả những thứ này hoạt động giống như bạn thường làm. Nếu nó là từ xa (như trong dịch vụ là trên một máy chủ ở đâu đó), có một cái gì đó bạn phải cài đặt trên máy chủ để cho phép gỡ lỗi từ xa. Nếu bạn cần thực hiện điều này trên STARTUP, bạn có thể thêm "dịch vụ giả" vào tệp thực thi của bạn, bắt đầu một (nạp EXE vào bộ nhớ), đính kèm quá trình rồi khởi động dịch vụ khác của bạn (với đầy đủ khả năng gỡ lỗi). Nó hoạt động tuyệt vời. –