Reputation: 16256
I recursively handle hierarchical data. If something goes wrong I'd like to collect additional info (that path to node that caused exception) on stack unrolling. I'd like to preserve original exception message and stack trace. This should be quite popular task but I cannot find any support for this in .NET. How could I implement this?
I tried to catch exception and rethrow my own exception supplying additional data in recursive function, or to store additional data in original exception Exception.Data. The problem is I haven't managed to provide correct stack trace which should include original exception stack trace + stack trace for my recursive function calls unrolling up to the place where I handle the exception.
My code looks like:
void func(...)
{
try
{
...
func(...);
}
catch (Exception ex)
{
Rethrow(ex, localData);
}
}
How Rethrow()
can be implemented?
EDIT:
I found that this happens only with Mono, not .NET. Yes, in .NET throw;
works fine. In Mono it doesn't, at least in version I use (custom build of Mono 2.8 for Unity3D). Example:
static void CheckRethrow()
{
try
{
f(0);
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}
static void f(int i)
{
try
{
if (i > 3)
throw new Exception("some message");
f(++i);
}
catch (Exception ex)
{
throw;
}
}
output call stack:
f (Int32 i) (at Test.cs:18)
CheckRethrow() (at Test.cs:9)
As you can see, couple of calls to f()
are missing in this call stack.
Upvotes: 1
Views: 897
Reputation: 6556
Just use the key throw
try {
} catch (Exception ex){
throw;
}
Upvotes: 1
Reputation: 77295
In .NET, almost all exceptions feature a member called InnerException
. You can have multiple exceptions or a chain of exceptions that way.
void func(...)
{
try
{
...
func(...);
}
catch (Exception ex)
{
throw new MyOwnExceptionWithLocalData(localData, ex);
}
}
Alternatively, although I have not tested it, you can add info to your exception and preserve it's stack trace by not mentioning the variable:
void func(...)
{
try
{
...
func(...);
}
catch (Exception ex)
{
ex.Property = value;
throw; // Note: no variable name here, will throw last exception and preserve stack trace
}
}
Upvotes: 4