On Thu, Jan 28, 2016 at 3:44 PM, Domagoj Saric <dsaritz@gmail.com> wrote:
On 28.1.2016. 21:02, Emil Dotchevski wrote:
Have you considered using Boost Exception? It lets you add arbitrary data to exception objects, even after they have been thrown, regardless of their type -- see http://www.boost.org/doc/libs/release/libs/exception/doc/error_info.html. The general idea is to adopt a strategy where the exception objects are augmented with any, even platform-specific relevant data, which then the catch site can analyze to choose the correct handling.
Hopefully these efforts will bring us to a solution that will do away with the, IMO, false dichotomy between "errors" and "exceptions" (<system_error> vs <exception>) - rather we will start thinking only about "errors"/error objects which can be transfered in two different ways - like a ball in a rugby game - it can be passed 'on foot' hand to hand or it can be thrown over intermediate players to its final destination (only with errors its in reverse - they are mostly passed/returned or thrown 'backwards':). IOW things like error_info will be applicable to 'the' standardized error type(s) that functions also return, not just throw.
You could theoretically pass exceptions function-to-function by exception_ptr but that seems backwards, no pun intended. :) Anyway, my point is that there are two ways one can go about solving the problem of transporting error codes. One is what seems to be the path you're taking, where you design a common API that can fit all error codes on all platforms. On the other hand, the Boost Exception approach sidesteps this difficult problem. Let's take socket errors for example, which on POSIX are communicated by the OS through errno, while on Windows there is the GetLastError function. Using the Boost Exception approach, you would always store the errno into any socket exception object, and on Windows you'd also store the GetLastError code. At the catch site, regardless of the platform, you can put in logic that takes correct action based on the presence or absence of any particular error_info: catch( socket_error & e ) { int const * e1=get_error_info<errinfo_errno>(e); assert(e1!=0); //errno must be present in all socket_error objects if( int const * e2=get_error_info<errinfo_GetLastError>(e) ) { //Both errno (*e1) and GetLastError (*e2) codes available. } else { //No GetLastError, use errno only. } } Emil