Your code-sample:
Done right:
When throwing the FileNotFoundException you include the ArgumentException as an inner exception.
Could be done better:
You could include the name of the file that could not be found by using this constructor instead:
public FileNotFoundException(string message, string fileName, Exception innerException)
(Please also refer to solution 2)
Some general rules for Exception-handling:
(Don't consider these points as exhaustive.)
- When throwing a new exception after catching one, put the previous exception as an inner exception into the new one. (In general.)
- When re-throwing the same exception as just caught, dont do
throw ex;
(because that will reset the stacktrace) but simply
throw;
- Don't clutter your code with exception-handling. Only catch exceptions for these purposes: 1) Logging 2) Trying to remedy the failure 3) Re-throwing it after adding additional information about the error to it
1
4) Putting it into another exception in order to provide additional information about the error
1
. Otherwise just let exceptions "bubble up". The only "mandatory" exception-catching would be at the top-level of your program (e.g. in the Main()-method) in order to log it. In reverse, this means:
- Don't swallow exceptions without doing anything.
(In general. There might be rare exceptions, which should be considered carefully.)
- When available, use versions of methods that don't throw an exception in case of failure but return a boolean success-flag (e.g. Int32.TryParse(..) instead of Int32.Parse(..)).
- Don't (ab)use exceptions for control-flow.
(In general. It
might be o.k. locally, e.g. for re-attempting to read user-input until it is accepted. Please see the first comment below.)
- Exceptions should be exceptional. Don't throw exceptions for things that happen all the time.
1
:
The message of the exception is not the only information that an exception can carry. You can store further information about an error in other properties, e.g.:
The Data-Property[
^]
The Source-Property[
^]
Depending on the concrete Exception, there can be more, e.g.:
The FileName-Property[
^] of FileNotFoundException
The ParamName-Property[
^] of ArgumentException
And of course you can create your custom Exceptions and implement custom properties for them to carry your custom error-information.
A very good blog-post about exception-handling:
http://www.hanselman.com/blog/GoodExceptionManagementRulesOfThumb.aspx[
^]
MSDN on exceptions and exception-handling:
https://msdn.microsoft.com/en-us/library/ms173160%28v=vs.110%29.aspx[
^]
Edit: Incorporated suggestions from Sergey Alexandrovich Kryukov's comment below.