Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If an exception is caught and then rethrown, then its stack trace will appear as though the exception occured at the point of the rethrow rather than the original place. Hopefully, there is not much of that stuff going on in your code. If not, then the stack trace alone should be sufficient to distinguish the exception locations.</p> <p>Another issue is whether the stack traces will be identical so that they do not appear to be two different exception when they are really the same. This, also, should not be a problem, since the stack traces are, in my experience, identical. (The ToString() results on the exception object will not, in general, be identical.)</p> <p><strong>UPDATED</strong></p> <p>There has been some discussion about exactly what the circumstances are that the <code>Exception.StackTrace</code> will be corrupted. The basic rule is that any time </p> <pre><code>throw *expression*; </code></pre> <p>is executed, then the <code>Exception</code> object that <code>*expression*</code> identifies will have its <code>StackTrace</code> property set. If the <code>*expression*</code> is omitted </p> <pre><code>throw; </code></pre> <p>then the StackTrace will not be effected.</p> <p>I could not find any terminology for these two forms, so I will call them "explicit" and "implicit" respectively. Note that it doesn't matter whether the exception object that <code>*expression*</code> resolves to is <code>new</code> or an already-existing object.</p> <p>Here is a program to illustrate this behavior:</p> <pre><code>using System; namespace FunWithExceptions { class Program { static void Main(string[] args) { try { Replace(); } catch (InvalidOperationException ex) { DisplayResult("Replace resulted in", ex); } try { RethrowExplicit(); } catch (InvalidOperationException ex) { DisplayResult("RethrowExplicit resulted in", ex); } try { RethrowImplicit(); } catch (InvalidOperationException ex) { DisplayResult("RethrowImplicit resulted in", ex); } InvalidOperationException myException = new InvalidOperationException(); DisplayResult("myException starts with", myException); try { throw myException; } catch (InvalidOperationException) { } DisplayResult("myException changes to", myException); Console.ReadLine(); } static void ThrowAnException() { throw new InvalidOperationException("You messed up!"); } static void Replace() { try { ThrowAnException(); } catch (InvalidOperationException ex) { DisplayResult("Replace caught", ex); throw new InvalidOperationException("Another mistake."); } } static void RethrowExplicit() { try { ThrowAnException(); } catch (InvalidOperationException ex) { DisplayResult("RethrowExplicit caught", ex); throw ex; } } static void RethrowImplicit() { try { ThrowAnException(); } catch (InvalidOperationException ex) { DisplayResult("RethrowImplicit caught", ex); throw; } } static void DisplayResult(string context, Exception ex) { Console.WriteLine("{0} exception thrown at {1}", context, FirstMethodName(ex.StackTrace)); } private const string methodNamePrefix = " at FunWithExceptions.Program."; private static object FirstMethodName(string stackTrace) { stackTrace = stackTrace ?? string.Empty; if (stackTrace.StartsWith(methodNamePrefix)) stackTrace = stackTrace.Substring(methodNamePrefix.Length); int methodNameEndIndex = stackTrace.IndexOf(')'); if (methodNameEndIndex != -1) stackTrace = stackTrace.Substring(0, methodNameEndIndex + 1); if (stackTrace.Length &gt; 0) return stackTrace; else return "--empty--"; } } } </code></pre> <p>This program results in the following output:</p> <blockquote> <p>Replace caught exception thrown at ThrowAnException()</p> <p>Replace resulted in exception thrown at Replace()</p> <p>RethrowExplicit caught exception thrown at ThrowAnException()</p> <p>RethrowExplicit resulted in exception thrown at RethrowExplicit()</p> <p>RethrowImplicit caught exception thrown at ThrowAnException()</p> <p>RethrowImplicit resulted in exception thrown at ThrowAnException()</p> <p>myException starts with exception thrown at --empty--</p> <p>myException changes to exception thrown at Main(String[] args)</p> </blockquote> <p>The sixth line is the interesting one.</p> <p>There, I have now beat this point completely to death. :-)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload