I wanted to handle all internal errors gracefully, without program termination.
As discussed here, using _set_se_translator catches divide-by-zero errors.
But it does not catch, for example, C runtime library error -1073740777 (0xc0000417), which can be caused by format strings for printf which have the percent sign where they shouldn't. (That is just an example; of course we should check for such strings). To handle these, _set_invalid_parameter_handler is needed.
There are about ten other such handlers listed here.
In addition, this one will catch uncaught C++ exceptions: SetUnhandledExceptionFilter. Thus, it can be used together with the __set__ ... functions. (An article about using it in MSVC 2008.)
I want to catch any and all errors so I can handle them (by logging, throwing a modern C++ standard exception and returning an application-specific error code). Is there a single handler that catches everything?
See also this on StackOverflow.
I am using Visual Studio 2008.
I would caution against this.
Internal errors are not recoverable. If you divide by zero or whatever - the program is not recoverable.
If you turn a termination handler into something that continues the program running, you can have no assurances of the STATE of the program, and you can just crash and corrupt in different ways later. Imagine that the program was holding some locks or other resources at the time of the termination you diverted, for example!
Lets have a nasty example:
What happens if you don't terminate the program? What happens to the program the next time someone tries to log something?
I cannot emphasise this enough - you should use hooking termination methods for extra logging and such, and nothing else. You should always continue to exit afterwards.
There is a completely different class of error, that can be intercepted:
A lot of APIs communicate with the caller using return codes to signal error conditions. It is appropriate to use macros or helper functions to check these return codes and translate them into exceptions. This is because that choice is in your code where you can see it.
If you override the _set_errno handler or something, you'd cause code you hadn't wrote that expected the setter to return normally to not return, and it might not have completed its cleanup.
There is no universal handler. You need to install each one. I have used something like this:
Then in main or app init, I do this:
Note that this translates structured exceptions to regular exceptions but handles terminate (which gets called, e.g., when a nothrow() function throws an exception) by simply printing an error message. It is highly unlikely that you want to use a single handler for all different types of errors, which is why they don't provide it.