Michael Kay
Michael Kay

Reputation: 163252

C# How to rethrow an exception from an outer catch

I've read How to rethrow InnerException without losing stack trace in C#? and the answer here may be the same; on the other hand my situation is sufficiently different that someone might be able to suggest a better approach.

My simplified structure is

try {
  something();
} catch (MyException e1) {
  try {
    somethingElse();
  } catch (MyException e2) {
    throw e1;
  }
}

That is to say, calling somethingElse() is an attempt to recover from the original exception, and if the recovery attempt fails, I want to throw the original exception, not the one that arose from the recovery attempt.

I get a warning from the compiler about rethrowing exceptions losing the stack trace (and of course, I don't like leaving my code with warning conditions). But what should I do about it? My IDE (Rider) suggests changing the throw e1; to throw;, but that would presumably rethrow e2.

Are there any solutions short of the convoluted ideas proposed in the cited question for inner exceptions?

To be honest, I don't really care about the imperfect stack trace - I just want to get rid of the warnings.

Upvotes: 3

Views: 565

Answers (2)

Qwertyluk
Qwertyluk

Reputation: 479

There is the ExceptionDispatchInfo class.

This lets you capture an exception and re-throw it without changing the stack-trace:

public static void Method()
{
    try
    {
        Something();
    }
    catch (MyException e1)
    {
        try
        {
            SomethingElse();
        }
        catch (MyException)
        {
            //throw e1;
            ExceptionDispatchInfo.Capture(e1).Throw();
            throw;
        }
    }
}

A regular throw; after the .Throw() line is because the compiler won't know that .Throw() always throws an exception. throw; will never be called as a result, but at least the compiler won't complain if your method requires a return object or is an async function.

Original post Link

Upvotes: 3

zoldxk
zoldxk

Reputation: 1

There is no way to rethrow an exception from an outer catch block inside an inner catch block. The best way to achieve this pattern is to note whether or not the inner operation succeeded :

try {
  something();
} catch (MyException e1) {
   bool recovered=false;
  try {
    somethingElse();
    recovered=true;
  } catch {
    
  }
   if (!recovered) {
    throw;
  }
}

Upvotes: 4

Related Questions