On Mon, Jun 1, 2020 at 6:54 PM Gavin Lambert via Boost < boost@lists.boost.org> wrote:
This is analogous to nested exceptions, the exact context type is erased and the context is transported in an exception or in a leaf::result<T>.
That appears to be parallel exceptions, not nested exceptions. I don't think these are analogous, given that remote_try_catch appears to be using some kind of magic to figure out which captured context to inspect, but you would instead presumably need to tell it explicitly whether you are looking at the context of the top-level exception or the nested exception.
I see why you say it's not like nested exception. What you refer as magic
in remote_try_catch is actually simple: it itself has a local context<>,
and the internal machinery detects that the passed result<T> (or the
exception) wraps a context in it, and tells the wrapped context, through a
virtual function call, to spill its content which is captured in the local
context, and from then on everything proceeds as usual.
I'll add that the the lowest level API exposed by LEAF works directly with
the context<> type. You could:
leaf::context
2) A lower level function has failed but you don't want to report this as a new error so to speak, you just want to add more info to the existing failure. Ideally the two functions would use different error types, and in this case it'll just work, just use preload().
For a possible use case (I'm sure there are others), imagine a "safe file saver" class that uses backup files. The higher-level error reporting wants to report the filename that the caller was actually trying to save, and yet the underlying internal file API might want to report that the problem actually occurred when saving either the real file or the backup file.
Obviously the low-level function doesn't know that it's dealing with a backup file, so it would just have a generic e_filename.
And the higher-level function will likely want to report its intended filename as an e_filename as well, as that is the one the caller cares about.
But does that mean that it would need to (and is this even possible?) move the underlying low-level filename to a new e_real_filename or similar in order to give e_filename a different value?
Yes, possible. You write a handler that takes leaf::error_info, call its .error() to obtain the error_id of this error, then .load the new value for e_file_name.
This sort of thing seems like a flat error reporting model rather than a nested model, and flat errors tend to lose information. (Not that C++'s mechanisms for nested exceptions are particularly wonderful.)
Indeed. I try to use different types for different things. You're saying that both libs would use leaf::e_file_name, but really they shouldn't, it'd be better if each defines a type within its own namespace. After all, the reason why "flat" error reporting tends to lose information is that there isn't efficient storage to send everything over. With LEAF, there is -- just make sure all error info is properly namespaced.
(The reason why this is needed is that a context can hold no more than one object for each type. In principle this can be changed, in which case you could have two e_file_name stored in the same context, associated with two different error_ids.)
Presumably this would not be possible without either reintroducing memory allocation or pre-declaring the max number of possible nested errors either per-context or globally.
Yes, per context. But really I don't want to do that, it's rather inelegant.