Suppose I want client code to override exception behaviour. What is the most appropriate way of doing this? It is understood that the callback must not return to its caller: It should either abort, or throw an exception in the format catched by the client catch clause.
- A global singleton which is initialized during library startup
- An exception policy which is passed to each function that can throw an exception
- Skip this customization point
The first choice is likely to be easier after the library has been initialized, but suffers from initialization requirements, and threading issues.
try
{
MyExceptionPolicy ep;
MyLib::init(ep);
MyLibb::Foo bar; //Ctor will call method in ep
//use bar
}
catch(const MyExceptionType& obj)
{
cerr<<obj.message();
return -1;
}
return 0;
The second choice is more flexible, but results in an ugly API. I guess this is why we have the global standard streams, so one does not need to pass references to these objects everywhere.
try
{
MyExceptionPolicy ep;
MyLib::Foo bar(ep); //Ctor will call method in ep. Can be implemented as a template, resulting in compile-time dispatch, rather than runtime dispatch.
//use bar
}
catch(const MyExceptionType& obj)
{
cerr<<obj.message();
return -1;
}
As an alternative approach, it is possible to use multiple catch clauses. This does not require an ExceptionPolicy
but, requires one catch clause per involved library, again making client code look ugly (if-else style exceptions).
try
{
MyLib::Foo bar;
//use bar
}
catch(const MyLib::ExceptionType& obj)
{
cerr<<obj.messageMyLibWay();
return -1;
}
catch(const MyExceptionType& obj)
{
cerr<<obj.message();
return -1;
}