Most advice concerning error handling boils down to a handful of tips and tricks (see this post for example). These hints are helpful but I think they don't answer all questions. I feel that I should design my application according to a certain philosophy, a school of thought that provides a strong foundation to build upon. Is there such a theory on the topic of error handling?
Here's a few practical questions:
- How to decide if an error should be handled locally or propagated to higher level code?
- How to decide between logging an error, or showing it as an error message to the user?
- Is logging something that should only be done in application code? Or is it ok to do some logging from library code.
- In case of exceptions, where should you generally catch them? In low-level or higher level code?
- Should you strive for a unified error handling strategy through all layers of code, or try to develop a system that can adapt itself to a variety of error handling strategies (in order to be able to deal with errors from 3rd party libraries).
- Does it make sense to create a list of error codes? Or is that old fashioned these days?
In many cases common sense is sufficient in developing a good-enough strategy for dealing with errors. But does anyone know of a more formal/"scholarly" approach?
PS: this is a general question, but C++ specific answers are welcome too (C++ is my main programming language for work).
Edit
On second thought, perhaps a set of guidelines is sufficient after all, as long as it leaves no areas uncovered.
The advice to "handle the error if you can or propagate" answers a lot of questions for me.
Update
Actually, after some thinking I find that it boils down to three simple rules:
- Use a top-down approach when it comes to catching errors. Write 'try/catch' blocks in all your code's entry points: main(), event listeners, timer callbacks, etc... Log the error inside the catch blocks.
- With these "safety nets" in place you can now throw without having to worry about unhandled exceptions. Make 'throw' your default response to (exceptional) error conditions. Just make sure you have RAII Protection.
- Where needed write extra catch handlers closer to where the exception is thrown. This will often not be necessary.
This strategy seems answer most of my questions:
- How far should I let my errors propagate? Until the top-level handlers. Refine for specific cases.
- Where should I do logging? In the catch blocks.
- Should I adapt a error handling strategy that can adapt itself to different error handling strategies of other libraries? If the library returns an error code then you can throw an exception.
- Does it make sense to create a list of error codes? Not sure, probably not.