How to write an attribute that catches exceptions and removes stacktrace?

I want to write an attribute for a function (or class) that will catch any exception that is thrown and set its StackTrace property to string.Empty . How can i do this?

EDIT:

If I can’t do this in simple C #, how can I do this in C # with PostSharp?

+6
source share
2 answers
 [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 } } } 

You really need to throw a new exception. The @Ani example will simply rebuild the exception that was already sent with the same stack trace (this is the same because of what you got in this aspect). Throwing a new exception will "modify" the stack trace, but will not delete it. If you want to remove it, you will need to throw your own class, which overrides the stack trace property. passing the old exception to the new exception will make the old exception an internal exception (if you want it)

You can accomplish this with and without PostSharp. The key is your own exception class.

Given the following code

 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; } } 

conclusion

in ConsoleApplication5.MyAspect.OnException (MethodExecutionArgs args) in C: \ T est \ Program.cs: line 69 at ConsoleApplication5.Program.Test3 () in C: \ Test \ Program.cs: line 59
in ConsoleApplication5.Program.Test2 () in C: \ Test \ Program.cs: line 47

in ConsoleApplication5.MyAspect.OnException (MethodExecutionArgs args) in C: \ T est \ Program.cs: line 69 at ConsoleApplication5.Program.Test3 () in C: \ Test \ Program.cs: line 59
in ConsoleApplication5.Program.Test2 () in C: \ Test \ Program.cs: line 52
in ConsoleApplication5.Program.Test1 () in C: \ Test \ Program.cs: line 34

in ConsoleApplication5.Program.Test1 () in C: \ Test \ Program.cs: line 39 in ConsoleApplication5.Program.Main (String [] args) in C: \ Test \ Program.cs: line 19

+3
source

The original trace of the exception stack is stored in the field of the Exception class. If you want to remove it without creating your own exception type, you can remove it using reflection as follows:

 [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); } } } 

Your exception will no longer contain a stack trace.

Edit Of course, you can do the same thing without PostSharp, just do it in the catch .

+3
source

Source: https://habr.com/ru/post/907490/


All Articles