Is it antipattern to catch all exceptions all at once?

What is bad such an approach:

try { foo(); } catch (Exception e) { // handle <-- разумеется, тут реальная обработка, а не подавление исключений } 

Without specifying what specific exceptions I want to handle.

Suppose I have in try ... catch wrapped code working with the file system, for specifics - copying the file .

The documentation has as many as 8 options for exceptions that this method can throw out - should a good programmer carefully write out all possible exceptions and periodically check that Microsoft will not add new ones?

I heard that you can generalize exceptions and not to write PathTooLongException , DirectoryNotFoundException and DirectoryNotFoundException every time, but once to handle an IOException from which they all inherit. This helps to reduce the number of catch blocks, but not by a lot (in the example with File.Copy, it can be reduced by 4, a total of 8). Is this the correct approach or does it also have its own nuances?

  • one
    Absolutely nothing, on one condition: you know what you're doing. There are often problems with writing code, and more often with those who pay for this code. - bipll
  • one
    If the handle does not remain a comment, then all the rules. The main thing is not to ignore exceptions. When you need to handle an exception in a certain way (and not just register it, say in the log) then add additional handlers) - vp_arth
  • DirectoryNotFoundException is specified twice. I do not know sisharp, so I can not fix it. - val

2 answers 2

You describe some very tiny rule and make it absolute. Fortunately, there are no such hard rules in nature, and, during development, the programmer, both in this case and in all other cases, should also use his head.

For example, the first question in handling an exception that may arise is whether the called method did its work? Or, if you call a third-party service on a timer, where would you like to forward an exception? Is the calling code interested in the problem of the called function at all?

For example, if you do the same thing on a timer, it’s just that a third-party service works, then it doesn’t work, then it makes sense to write problems with it to the log and, perhaps, notify someone about problems, no matter what, the network has fallen off or the server returns 500 - the timer is not interesting.

But if you are copying files, then the calling code will probably be interested to learn about the result of the operation. In this case, if you catch all the exceptions, it is only to log in and straighten the exception further, higher in the stack.

As to what types of exceptions to catch, everything is simple. If you have a difference between FileNotFoundException and DirectoryNotFoundException in your logic, then intercept them with separate handlers. If there is no difference, and you are not interested in the specifics of the problem, only its presence, then intercept one.

    Catch exceptions by type when you want to run a separate script for a specific exception. Suppose if you have FileNotFound exception and only in this case you want to return FileNotFoundResult , in all other cases you just want to make a log:

     try { foo(); } catch (FileNotFound exception) { return new FileNotFoundResult() } catch(Exception ex){ logger.Log(ex.Message) } 

    Since all exceptions are inherited from the parent class Exception, its catch statement must be specified at the very bottom