3 using System
.Runtime
.CompilerServices
;
6 class CustomException
: Exception
9 public CustomException (int value) => this.Value
= value;
14 static CustomException e
;
16 [MethodImpl(MethodImplOptions
.NoInlining
)]
17 static void ThrowCustomException ()
19 throw new CustomException(1);
22 [MethodImpl(MethodImplOptions
.NoInlining
)]
26 ThrowCustomException ();
27 } catch (CustomException ex
) {
29 // so, the original exception has two frames
34 static int FrameCount (Exception ex
)
36 string fullTrace
= ex
.StackTrace
;
37 if (fullTrace
== null)
38 throw new Exception ("Empty trace found!");
40 string[] frames
= fullTrace
.Split(new string[] { Environment.NewLine }
, StringSplitOptions
.None
);
43 frames
= frames
.Where (l
=> !l
.StartsWith ("[")).ToArray ();
48 // throws on false anyway
49 [MethodImpl(MethodImplOptions
.NoInlining
)]
50 static bool CheckTrace (Exception ex
, int numFramesToExpect
, bool whatToReturn
= true)
52 int frames
= FrameCount (ex
);
53 if (frames
!= numFramesToExpect
) {
54 throw new Exception ($"Exception carried {frames} frames along with it when it should have reported {numFramesToExpect}. Full trace:\n---\n{ex.StackTrace}\n---");
60 [MethodImpl(MethodImplOptions
.NoInlining
)]
61 static void ThrowCustomExceptionWithValueButFailsToCatchWithFilter ()
64 ThrowCustomException (1);
65 } catch (CustomException ce
) when (ce
.Value
== 9999) {
66 throw new Exception ("This should NEVER be hit");
70 [MethodImpl(MethodImplOptions
.NoInlining
)]
71 static void ThrowCustomException (int value)
73 throw new CustomException (value);
76 [MethodImpl(MethodImplOptions
.NoInlining
)]
77 static void ThrowFileNotFoundException ()
79 throw new FileNotFoundException ();
82 public static void Main ()
87 // Filter returns false
88 // Original exception @e had two frames, but after throwing here it
92 } catch (Exception ex
) when (CheckTrace (ex
, 1, true)) {
96 // Throw + filter fails, then filter matches at next level
98 ThrowCustomExceptionWithValueButFailsToCatchWithFilter ();
99 } catch (CustomException ex
) when (CheckTrace (ex
, 3, true)) {
103 // Throw + filter fails, then filter matches, exception re-thrown and caught
106 ThrowCustomExceptionWithValueButFailsToCatchWithFilter ();
107 } catch (CustomException ex
) when (CheckTrace (ex
, 3, true)) {
110 // this will truncate the trace now
113 } catch (Exception ex
) {
117 // Throw, filter matches, throw exception as-is, caught
120 ThrowFileNotFoundException ();
121 } catch (Exception e
) when (CheckTrace (e
, 2)) {
122 // trace should remain as is
125 } catch (Exception ex
) {