Adam Heeg
Adam Heeg

Reputation: 1714

Is there ever a reason to keep outer exception when there is an inner exception?

If an exception is caught and there is an inner exception does anyone know of a reason why that wrapper exception might ever need to be referenced for anything? I can't think of one, but want to double check.

Upvotes: 2

Views: 924

Answers (3)

supercat
supercat

Reputation: 81247

A common situation involving nested exceptions occurs when an object is asked to execute a delegate in some context. In many such cases, it's possible that various factors may prevent the object from executing the delegate in the expected fashion; an inability to execute the delegate would generally be indicated by throwing an exception. On the other hand, while almost any kind of exception that could be thrown for such a cause could also be thrown by the delegate being executed, exceptions thrown by the delegate should almost always be handled differently from exceptions thrown by the invoking object, and must thus be distinguishable from them.

A common remedy is to say that any exception which is thrown from within the invoked delegate will cause the invoking object to throw one particular kind of exception, and that exception will have the delegate's object as an InnerException. In the event that the delegate throws an exception which outer code wishes to handle, the outer code will often catch the wrapper exception without being interested in its stack trace or anything else, but will use the existence of the outer exception to determine that the inner exception was thrown by the delegate rather than the object that was invoking it.

Another more difficult situation with nested exceptions occurs when an attempt to clean up from one exception ends up triggering another. For example, an exception occurs while a program is generating data which is supposed to be written to a file. While unwinding from that exception, the program tries to close the file (committing pending data to disk as needed) but that operation fails as well. In that case, both exceptions are likely to be extremely important. Even if the first exception was expected, the fact that data was not written to disk is likely a problem that shouldn't be ignored. Unfortunately, none of the top three Object-oriented languages/frameworks (C++, Java, or .NET) really has any good way of handling this scenario.

Upvotes: 1

GPicazo
GPicazo

Reputation: 6676

Absolutely. The outer exception is technically the container for you full stack trace, useful for complex debugging scenarios. Here is a very fictional example (not too complex) to explain what I mean.

Assume you have a very generic logging library that allows you to configure the logging properties (like log target as db, file, ...). The configuration can be done when a Logger object is instantiated, but can also be overriden on a per Logger.Log(...) call basis. The Logger does not validate configuration, it simply does it's best to log the data and throws an exception if it cannot be done.

Now assume you have an application that uses the above library. The application uses an IoC to instantiate a global instance of the logger, and the IoC sets up the default configurations correctly, such that using those configuration settings always works perfectly. In various places in the application, certain parts of the application make .Log(...) calls, but override the logger configurations, some of which work, and others which cause exceptions to be thrown. Assume that this application was written by someone who throws away wrapping exceptions and only reports back inner most exceptions.

In the above scenario, not totally unrealistic, if only the inner exception is considered, then when the logging fails, we will know that it failed while trying to Log using the logging library, but may not have enough information to know where in the consuming application the logging attempt was made. On the other hand, if we have the outer exception, we can simply inspect it to determine where in the application the error originated. Makes debugging a lot easier.

Upvotes: 3

usr
usr

Reputation: 171216

Of course. When debugging a problem any information can help. The inner exception usually contains only a small part of the full stack. Usually, wrapping exceptions add semantic information.

For example, Entity Framework exceptions tell you quite specific things about EF concepts. But they also let you reach into the InnerException to obtain a SqlException.

Starting with .NET 4.5 SqlException often has a fairly meaningless Win32Exception as an inner exception. You certainly don't want to rely on "file not found" when the SQL Server instance could not be reached over the network. (This is a true example.)

Why would you throw away error information?!

If you want to make use of an inner exception for handling an error then just walk the exception chain and pick the exception you are interested in.

Upvotes: 1

Related Questions