What is the difference between `throw;` and `throw ex;`?

C# Error Handling Intermediate 1–2 Yrs2–3 Yrs Conceptual 1 min read

Quick Answer

throw; re-throws the current exception preserving its original stack trace and throw point. throw ex; re-throws it but resets the stack trace to the current line, hiding where the error actually originated. Always use bare throw; when re-raising.

Bare throw; re-throws the exception you caught with its original stack trace intact — so the log still points at the line that actually failed. throw ex; re-throws the same object but resets the stack trace to the current line, so you lose the real origin and your logs blame the catch block. So the rule is: use throw; to re-raise. If I want to add context I wrap it in a new exception and pass the original as the inner exception.

  • With throw ex;, your logs point at the catch block instead of the line that failed — much harder to debug.
  • If you need to re-throw from a different context (e.g. after storing an exception), use ExceptionDispatchInfo.Capture(ex).Throw() which preserves the trace.
  • To add context, wrap: throw new DataAccessException("loading order failed", ex); — the original is kept as InnerException.