Although only types derived from Exception
can be thrown or caught, the are very few rules about what such types can do or contain, and such rules are not sufficient to guarantee the existence of any general-purpose means via which instances of any and all such types can be recreated. Certainly types can be designed to be "difficult", and while most types would have little reason for doing so, there's no guarantee that the creator of a type wouldn't find some benefit to a design which happens to be incompatible with any straightforward copying approach.
For example, consider the following sketch of an exception derivative:
void SillyException : Exception
{
SillyException shouldBeThis;
public SillyException()
{
shouldBeThis = this;
}
public override String ToString()
{
if (shouldBeThis != this) doSometingBad();
return base.ToString();
}
}
Code which knows about field shouldBeThis
might be able to use Reflection to set it, but there would be no way for code which had no reason to suspect the existence of a variable to properly set it to this
. While that particular example is of course highly contrived, there are a variety of similar reasons why copying an exception may be essentially impossible. For example, a class might keep a ThreadStatic
variable which holds the exception--if any--thrown by the last attempted operation on the class on that thread, and so that if cleanup fails it can build a composite exception which combines the original exception with cleanup exception(s). If multiple exceptions include references to each other, an attempt to copy the exception which isn't aware of the different exceptions and their relationships could easily result in a broken object graph, which could cause an attempt to examine and report what happened to crash with a stack overflow.
If you know enough about the exceptions that will be thrown to know that such designs are not an issue, then an approach using generics and Reflection might be usable, but the suitability of such designs will depend upon exactly what you know and exactly what you're trying to do.