Exception 如何编写捕获异常并删除stacktrace的属性?
我希望为函数(或类)编写一个属性,该属性将捕获抛出的任何异常,并将其Exception 如何编写捕获异常并删除stacktrace的属性?,exception,c#-4.0,stack-trace,postsharp,Exception,C# 4.0,Stack Trace,Postsharp,我希望为函数(或类)编写一个属性,该属性将捕获抛出的任何异常,并将其StackTrace属性设置为string.Empty。我该怎么做 编辑: 如果我不能在普通C#中实现这一点,那么如何使用PostSharp在C#中实现这一点 [Serializable] public class MyAspect: OnExceptionAspect { public override void OnException(MethodExecutionArgs args) {
StackTrace
属性设置为string.Empty
。我该怎么做
编辑:
如果我不能在普通C#中实现这一点,那么如何使用PostSharp在C#中实现这一点
[Serializable]
public class MyAspect: OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
throw new MyCustomException(args.Exception);
}
}
public class MyCustomException : Exception
{
public override string StackTrace
{
get
{
//return new StackTrace(10).ToString(); //Skip frames
return string.Empty; //Return empty string
}
}
}
实际上,您必须抛出一个新异常@Ani的示例将简单地重新显示已使用相同堆栈跟踪抛出的异常(这是相同的,因为您是如何到达方面的)。抛出新异常将“更改”堆栈跟踪,但不会擦除它。如果要删除它,则需要抛出覆盖堆栈跟踪属性的自己的类。将旧异常传递给新异常将使旧异常成为内部异常(如果需要)
您可以使用PostSharp或不使用PostSharp来完成此操作密钥是您的自定义异常类。
给定以下代码
class Program
{
static void Main(string[] args)
{
try
{
Test1();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace + Environment.NewLine);
}
Console.ReadKey();
}
private static void Test1()
{
try
{
Test2();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace + Environment.NewLine);
throw e;
}
}
private static void Test2()
{
try
{
Test3();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace + Environment.NewLine);
throw;
}
}
[MyAspect]
private static void Test3()
{
throw new InvalidOperationException();
}
}
[Serializable]
public class MyAspect : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
throw args.Exception;
}
}
输出是
在控制台Application 5.MyAspect.OneException(MethodExecutionArgs
C:\T est\Program.cs中的args):第69行
C:\Test\Program.cs中的ConsoleApplication5.Program.Test3():第59行在C:\Test\Program.cs中的ConsoleApplication5.Program.Test2()处:第47行 在控制台Application 5.MyAspect.OneException(MethodExecutionArgs C:\T est\Program.cs中的args):第69行 C:\Test\Program.cs中的ConsoleApplication5.Program.Test3():第59行
在C:\Test\Program.cs中的ConsoleApplication5.Program.Test2()处:第52行
在C:\Test\Program.cs中的ConsoleApplication5.Program.Test1()处:第34行 在C:\Test\Program.cs:行中的ConsoleApplication5.Program.Test1()处 39在控制台应用程序5.Program.Main(字符串[]args)中 C:\Test\Program.cs:第19行
异常的原始堆栈跟踪存储在
exception
类的字段中。如果要在不创建自己的异常类型的情况下删除它,可以通过反射将其删除,如下所示:
[Serializable]
public sealed class NoStackTraceException : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
RemoveStackTrace(args.Exception);
}
private void RemoveStackTrace(Exception exception)
{
FieldInfo stackTraceField = typeof(Exception).GetField("_stackTrace",
BindingFlags.NonPublic | BindingFlags.Instance);
if (stackTraceField != null)
{
// sets the value of _stackTrace to null
stackTraceField.SetValue(exception, null);
}
}
}
异常将不再包含堆栈跟踪
Edit当然,您也可以在不使用PostSharp的情况下完成同样的事情,只需在
catch
块中执行即可。有没有一种方法可以在不使用自定义类的情况下执行此操作?例如,如果我想删除抛出的系统.Exception
的堆栈跟踪,您可以使用反射,但实际上这不是您想在生产中执行的操作。我希望它是学术性的,或者只是为了测试。请参见@hmemcpy-answer。在Test1()方法中,为什么要使用“throw e;”而不是“throw;”?好奇:为什么要这样做?请参见下面我的答案,尽管我不鼓励这样做。异常的存在是有原因的,这是为了在发生异常时帮助调试。通过删除堆栈跟踪,可以有效地隐藏错误源,如果不进行调试,则无法找到错误源。如果出于某种原因担心隐私问题,您可以尝试对stacktrace进行模糊处理或加密(使用答案中描述的相同方法),以便稍后可以对其进行解密,比如从日志文件进行解密。这也是我需要的,原因是我需要将异常对象传递给Web服务,但由于某种原因,我无法让服务接受它。所以我可以传递消息和StackTrace,然后重新创建异常服务器端。