What is the difference between `throw;` and `throw ex;`?
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 thecatchblock 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 asInnerException.