I am fully aware that what I am about to ask is not good practice... but:
Let's say I have a class containing a function that I want to always return a value, but store any exceptions that might occur for later processing. Something Like:
public Exception _error { get; set; }
public bool IsValid()
{
try
{
//do something here to cause exception
return true;
}
catch (Exception ex)
{
_error = ex;
return false;
}
}
Now that I have stored the exception, is it at all possible to throw the exception from an outside method while maintaining both the original stack trace and exception type?
throw _error; //lose stack trace
throw new Exception("", _error) //lose type
Thanks for looking or answering.
EDIT:
Thanks to some additional points, I realize that the below idea only takes away information and doesn't really add or simplify the situation. Thanks again to everyone.
After pondering Pieter's answer and comments, I'm now wondering if making a wrapper Exception class like the below could be a partial solution. This overrides as much of the exception as possible to make the New exception look like its innerexception, including the stacktrace.. dirty I know, but interesting:
public class ExceptionWrapper : Exception
{
private Exception _innerException;
public ExceptionWrapper(Exception ex) : base("", ex)
{
_innerException = ex;
this.Source = ex.Source;
this.HelpLink = ex.HelpLink;
}
public override string StackTrace
{
get
{
return _innerException.StackTrace;
}
}
public override System.Collections.IDictionary Data
{
get
{
return _innerException.Data;
}
}
public override string Message
{
get
{
return _innerException.Message;
}
}
public new Exception InnerException
{
get
{
return _innerException.InnerException;
}
}
}
No, this is not possible.
However, you normally solve this is by wrapping the exception in a new exception:
throw new MyException("Wrapper", _error);
This does maintain the stack trace of _error
, but you do get a new exception. Your solution in your second example is the correct way of handling these cases.
Consider using reflection to create a wrapper exception of the correct type (Activator.CreateInstance) and calling the constructor that will accept the inner exception you have stored.
For example:
[Test]
public void test()
{
Exception ex = new ArgumentNullException();
Exception wrapped = (Exception)Activator.
CreateInstance(ex.GetType(), "wrapped", ex);
Type expectedType = typeof(ArgumentNullException);
Assert.IsInstanceOf(expectedType, wrapped, "Is ArgumentNullException.");
Assert.AreEqual(ex, wrapped.InnerException, "Exception is wrapped.");
}
Update
In order to mitigate the constructor issue, you could consider using the default constructor (should be there for an exception that follows design guidelines, but not mandatory) and then patching up the new instance by setting its fields via reflection.
I agree the approach is highly "meh" it's more an exploration of an idea. I wouldn't recommend it.
The exception design guidelines require a default constructor, so this sort of behaviour may go on in the framework somewhere anyway. Perhaps for some sort of icky serialization\deserialization of exceptions across some sort of communications boundary?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With