2011-09-06 31 views
6

Tôi muốn ném ngoại lệ nhưng với thông báo tùy chỉnh và ngăn xếp stacktrace quá. Tôi đã trải qua nhiều chủ đề khác nhau.Ném ngoại lệ nhưng dấu vết ngăn xếp vẫn tồn tại

catch (Exception ex) 
{ 
throw; // Message is read only but stacktrace persist 
throw ex; // Message is readonly and strack trace also blows .. worst! 
throw new CustomException("My exception");// Message can be overridden but stacktrace lost 
throw new CustomException("My message",ex);// same as above. However if this constructor in exception class calls same constructor of base class then .. see below 
} 

Khi appraoch cuối cùng được sử dụng (với nhà xây dựng tùy chỉnh ngoại lệ gọi cơ sở constructor lớp), đầu ra trên màn hình của cái chết là một cái gì đó như:

**The remote server returned an error: (401) Unauthorized.** 

[WebException: The remote server returned an error: (401) Unauthorized.] 
original stack trace 

[NewException: newMessage] 
New Stack Trace 

Điều tốt là mọi thứ đều có trên màn hình. Nhưng, trên cùng, tôi muốn ngoại lệ của mình hiển thị tức là "tin nhắn mới" và không phải là tin nhắn gốc.

Do đó đối chiếu câu hỏi của tôi: LÀM THẾ NÀO tôi có thể hiển thị trên màn hình chết theo dõi ngăn xếp ban đầu nhưng có thông báo lỗi tùy chỉnh?

+1

Đây có phải là một dịch vụ web trả lại ngoại lệ? – Oded

+0

Trong ví dụ của tôi, nó thực sự là một cuộc gọi webservice. Tuy nhiên nó không quan trọng như ngoại lệ có thể có được bất cứ điều gì như DivisionByZero hoặc sqlException vv Ý tưởng là để cho người dùng biết về bản gốc stack theo dõi nhưng nhà phát triển cũng tùy chỉnh thông điệp ngoại lệ mặc định để giúp đỡ nhiều hơn. – helloworld

+0

Không, nó không phải là phi vật chất. Các khung công tác Webservice có những ý tưởng riêng của họ về các ngoại lệ. –

Trả lời

8
throw new CustomException("My message",ex);// same as above (... stacktrace lost) 

Kết luận của bạn trong các nhận xét sai trên trang cuối cùng. Stacktrace được giữ trong Ngoại lệ bên trong. Báo cáo chuẩn (bao gồm Exception.ToString()) sẽ báo cáo toàn bộ stacktrace. Đây là những gì bạn đang nhìn thấy khi bạn có được quyền xây dựng. (Luôn gọi đúng ctor cơ sở!).

Nhưng tôi không nhận ra [WebException]. Trong WCF, bạn cần

<serviceDebug includeExceptionDetailInFaults="true"/> 

Tôi đoán môi trường web của bạn có tính năng tương tự như triệt tiêu thông tin lỗi cho khách hàng.

3

Sử dụng phương pháp thứ tư của bạn là cách nó thường được thực hiện và mẫu được thiết lập. Bạn không nên nhầm lẫn việc xử lý ngoại lệ (hoặc nâng cao) với cách chúng được hiển thị hoặc đăng nhập, hoặc bất cứ điều gì.

Nếu bạn có đầu ra của (bắt) ngoại lệ được kiểm soát, tức là có thể thay đổi/viết mã tương ứng, bạn có thể chỉ cần sử dụng phương pháp Exception.ToString(), sẽ in ngoại lệ bên ngoài, bao gồm tất cả "bên trong".

Ghi chú: Đôi khi ngoại lệ bên trong không được hiển thị theo mục đích của ứng dụng. Ví dụ trong WCF (Windows Communication Foundation) ngoại lệ bên trong thậm chí không được chuyển từ máy chủ đến máy khách trừ khi IncludeExceptionDetails (thông qua cấu hình, mã, ...) được thiết lập. Điều này thường được thực hiện vì ngoại lệ bên trong được coi là chi tiết triển khai, có thể cung cấp cho kẻ tấn công thông tin có giá trị để phá vỡ ứng dụng của bạn.

0

Còn về việc ghi đè thuộc tính StackTrace thì sao?

class CustomException : Exception { 

    public CustomException(string message, Exception inner) : base(message, inner) { 
    } 

    public override string StackTrace { 
     get { 
      if (InnerException != null) { 
       return InnerException.StackTrace; 
      } 
      return base.StackTrace; 
     } 
    } 
} 
+0

cảm ơn! Đã thử nó ... Trong khi màn hình màu vàng của cái chết hiển thị, breakpoing trên trở lại InnerException.Stacktrace được gọi là ba lần và mọi lúc nó cho thấy stacktrace gốc. Nhưng kỳ lạ là nó vẫn hiển thị dấu vết ngăn xếp mới: ( – helloworld

+0

@enableDeepak: không biết nó sẽ làm cho vũ trụ sụp đổ trên chính nó ... xin lỗi: ( –

0

Tôi đồng ý, tùy chọn 4 thường là tốt nhất ...

Tuy nhiên, trong phát triển, tôi thấy nó rất hữu ích để đưa toàn bộ mệnh đề catch bên trong một #if (! DEBUG), với một cuối cùng bên ngoài nó (để cho phép biên dịch trong chế độ Gỡ lỗi):

#if (!DEBUG) 
catch (Exception ex) 
{ 
    // Catch logic for Release mode 
} 
#endif 
finally { } 

Điều này làm cho điểm ngắt API tại thời điểm xảy ra lỗi, thay vì ở cấp cao nhất.

Chỉ cần không tạo thói quen #if ...trong hầu hết các trường hợp khác, sử dụng

[Conditional("DEBUG")] 

trước một phương pháp thay

Các vấn đề liên quan