
Taking into account our previous discussions I expected that you will rather try to convince me that what I was going to do is bad rather then try to add non-const get_error_info. :)
From your description, it seems the first thing you need to consider is what is the exception safety guarantees of the function that notifies the listeners, as a whole.
1) If only basic exception safety guarantee is required, then you simply don't worry about the exceptions: if a onNotify throws, it'll propagate the exception out.
2) If strong exception safety guarantee is required, then you must make sure that if a onNotify throws, the effects of the already completed onNotifys can be undone without an error. Then, you propagate the exception as in 1).
3) Nothrow exception safety guarantee: you know onNotify won't throw.
It seems you're leaning towards 3). If that's the case, if an onNotify throws, you have a bug. Therefore I don't think it is a good idea at all to "keep going". If I were you, I'd just catch(...) and assert(), possibly after logging boost::current_exception_diagnostic_information() somewhere.
I thought about it a lot. :) And in this case it is not so simple. I would prefer 3) however I don't thing that reasonable system can be done assuming 3) (without large risk of exception data loss - since I consider premature excepting logging as exception data loss). So 3) is not acceptable (especially taking into consideration that standard gives almost no guarantees on exception throwing so virtually anything non-trivial might possibly throw). 2) would be great to. However is not possible as well. Mainly because there are operations which might fail during reverting which defeats this idea. So 1) is left and this is what I have now. But I would like something better. I would like to notify all listeners even if they any of them fails. Because this is what observable is supposed to do - notify listeners. If I allow it to skip further onNotify calls once an exception is thrown I am in a state which is almost surely unrecoverable because even if I deal somehow with the error I have no way of continuing notifications from the interrupt place. I could add such feature but it would be rather complex.
That said, if you want to attach a bunch of exception_ptrs to a boost::exception, you could just use different tags:
typedef boost:error_info<struct onNotifyFoo_,boost::exception_ptr> onNotifyFoo; typedef boost:error_info<struct onNotifyBar_,boost::exception_ptr> onNotifyBar;
This obviously will not do since number of listeners is known at runtime.
Alternatively, you can collect them all into a std::vector<boost::exception_ptr>. When you're done calling onNotifys, if the vector is not empty you just throw an exception, adding the vector to it.
If you are concerned about the (remote?) possibility of a std::bad_alloc propagating instead of your exceptions, you shouldn't be because that could happen anyway. To throw an exceptoin, the runtime needs memory to store the exception object. In some implementations that memory comes from the heap, so an attempt to throw any exception whatsoever could result in a std::bad_alloc instead (the runtime is required to have enough memory to throw a std::bad_alloc.)
Yes. I described that method as an alternative. And yes I am concerned with risk of std::bad_alloc. And yes I cannot avoid it fully anyway. But Boost exceptions objects are small so the risk is marginal. And if this happens anyway then I consider it an error so fatal that I will not recover from it anyway - just unwind the stack. Just because you cannot avoid accident does not meant that you will put yourself to an unnecessary risk, right? Want another example? What about stack trace? I could have a sequence container in the exception and in each catch in which I will rethrow the exception I would add source code location data to have better diagnostic information. Obviously I cannot do this with fixed number of separate error_infos (without loss of data). And again I could each time get the stack trace, add new entry and reset the stack trace with new collection. But with the same problems as previously. Unnecessary risk of failure and decreased execution speed. But I will not only defend myself but rather strike back now! :) (Keep in mind it is a joke!) What are the reasons to not have non-const get_error_info? I haven't look into implementation but I guess it requires almost no work at all to add (and maintain) it. I don't see also design purpose. If you allow to not only modify once created exception object but also modify a const exception object (I agree it is useful and convenient and I wouldn't like it being removed) then you should allow to modify data in that object. I don't see reason to treat the data in special way. Especially that after all I can overwrite it with different value so in fact achieve the same but in less efficient and safe method. Adam Badura