This is about wrapping the exception handling logic in some sort of class. While writing c++ code, many time we need to catch many type/variants of exception depending on what client throw. This lead us to write similar types of code(many times) in catch() clause.
In below sample example, I have written the function(), which can throw exception in the many possible form.
I wanted to know is it possible to write/wrap such logic in the form of class so that end user would have to write similar types of code at once place?. Does it make any sense or it has any meaning?
#include<vector>
#include<string>
#include<exception>
#include<iostream>
// this function can throw std::exception, std::string, int or unhandled
void function() {
std::vector<int> x{1,2,3,4,5};
auto val = x.at(x.size()); //throw out-of-range error
}
int main() {
try { function(); }
catch(std::exception& e) { std::cout<<e.what()<<std::endl; }
catch(std::string& msg) { std::cout<<msg<<std::endl; }
catch(int i) { std::cout<<i<<std::endl; }
catch(...) { std::cout<<"Unhandled Exception"<<std::endl; }
return 0;
}
So far I thought in this way and below is the pseudo logic.
class exceptionwrapper{ exceptionwrapper(function pointer* fp) { // functions which would be executing inside try } ~exceptionwrapper() { // all catch() clause can be written over here // or some other member function of this class } };
The object of this class can be instantiated in the main() in this way.
int main() {
exceptionwrapper obj(function);
//here execptionwrapper destructor would take care about calling all type of catch
}
What you're asking for is possible, but I don't think it's very useful. First let's implement a mechanism to accept a callable object, and its associated arguments, which we'll invoke in the destructor of
exception_wrapper
.This makes use of the C++14
std::integer_sequence
; if that's not available on your implementation there are several answers on SO that show how to implement it yourself (this one for instance).To use it, create an
exception_wrapper
object, and your function will be invoked when the destructor executes.Live demo
Now, I don't think this is useful because in general you should only catch exceptions if your code is able to handle them, and continue operating normally. Otherwise let them propagate to the top level where you might want to install a handler so it allows you to exit the program gracefully.
Given that, it's unlikely that there'll be a common approach to handling all exceptions thrown by your code, which greatly reduces the utility of
exception_wrapper
as implemented. You could modify it to take another callable argument, the exception handler that will be passed thestd::exception
object that was caught, which makes the class a little more generic.Additionally, invoking the function in the destructor means you cannot pass the return value, if any, back to the caller. This can be fixed by invoking the function within
exception_wrapper::operator()
instead, but that then adds the wrinkle of what to return in the case an exception is indeed thrown, and you've suppressed it.Finally, do not write code that throws types that are not derived from
std::exception
. This makes your code unidiomatic, and if you do want to handle the exception, you'll need to litter the code with severalcatch
statements, like you have in your example.It is possible using
std::exception_ptr
:Live demo link.
You can also achieve this without
std::exception_ptr
, just putthrow;
in place ofstd::rethrow_exception(e);
, hoping this function will be invoked only if there is an active exception being handled (otherwise your program will beterminate()'
ed):Yet another live demo link.