2011-09-06 45 views
6

我想抛出一个异常,但自定义消息并坚持栈跟踪。我已经通过各种线程。抛出异常,但坚持堆栈跟踪

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 
} 

当最后appraoch使用(与自定义异常构造调用基类的构造函数),输出对死亡的屏幕是一样的东西:

**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 

的好处是一切都没有在屏幕上。但是,最重要的是,我希望我的例外显示“新消息”,而不是原始消息。

因此,调和我的问题:如何显示在死亡的屏幕上的原始堆栈跟踪,但与自定义错误消息?

+1

这是一个Web服务返回的异常? – Oded

+0

在我的例子中,它确实是一个web服务调用。然而,它是无关紧要的,因为异常可能是像DivisionByZero或sqlException之类的东西。想法是让用户知道原始堆栈跟踪,但是开发人员还可以自定义默认异常消息以获得更多帮助。 – helloworld

+0

不,它并不重要。 Webservice框架对异常有自己的想法。 –

回答

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

您在评论中的结论是错误的最后一个。堆栈跟踪保存在内部异常中。标准报告(包括Exception.ToString())将报告完整的堆栈跟踪。这是当你获得构造函数时你所看到的。 (始终呼叫正确的基地电话!)。

但我不承认[WebException]。在WCF你需要

<serviceDebug includeExceptionDetailInFaults="true"/> 

我想你的Web环境有一个类似的功能,抑制错误信息对客户端。

3

使用你的第四种方法是它是如何通常完成和已建立的模式。您不应该将异常处理(或提升)与它们的显示或记录方式混淆起来,等等。

如果您控制了(捕获)异常的输出,即可以更改/编写相应的代码,您可以简单地使用Exception.ToString()方法,该方法将打印外部异常,包括所有“内部”异常。

备注: 有时,内部异常不会由应用程序有意显示。例如在WCF(Windows Communication Foundation)中,除非设置了IncludeExceptionDetails(通过配置,代码...),否则内部异常甚至不会从服务器传输到客户端。这通常是因为内部异常被视为实现细节,这可能会向攻击者提供有价值的信息来破坏您的应用程序。

0

怎样重写StackTrace属性?

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

谢谢!试过了......在显示死亡的黄色屏幕时,InnerException.Stacktrace返回时被称为三次,每次显示原始堆栈跟踪。但奇怪的是,它仍然显示新的堆栈轨迹:( – helloworld

+0

@enableDeepak:不知道它会导致宇宙崩溃在自己......对不起 –

0

我同意,选择4通常是最好的......

然而,在开发过程中,我发现把整个catch子句用#if内(!DEBUG),以最终它非常有用外面(允许在调试模式下编译):

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

这使得代替在顶层,在发生错误的位置点的API突破。

只是不养成#if的习惯...在几乎所有其他情况下,使用

[Conditional("DEBUG")] 

的方法,而不是前面