yandex / ozo

OZO is a C++17 Boost.Asio based header-only library for asyncronous communication with PostgreSQL DBMS.
PostgreSQL License
227 stars 46 forks source link

Does ozo throw exceptions? #219

Open jonesmz opened 4 years ago

jonesmz commented 4 years ago

Will, for example, ozo::execute throw an exception for reasons other than the CompletionToken provided to it throwing an exception?

thed636 commented 4 years ago

Hi, Michael!

Yes, potentially it may throw despite a СompletionToken behavior. This is not a common case but it is possible because of C++ nature (everything may throw an exception by default). That's why it is not marked as noexcept.

jonesmz commented 4 years ago

I don't really follow your answer. What code from ozo would throw?

thed636 commented 4 years ago

There is no certain logic that throws exceptions during the operation - error codes are used instead, but there are customization points that aren't specified as noexcept, so they may throw. E.g.: allocator may throw, send_impl specialization may throw, ozo::ostream::write() may throw on bad stream state and so on. Does it make sense?

Do you have any problem with an exception during the operation?

jonesmz commented 4 years ago

I'm not currently seeing any exceptions from ozo, no.

I'm asking because I'm trying to make improvements to my code that uses ozo, and part of that is investigating exception guarantees and placing the noexcept keyword where it made sense, or wrapping function calls in try-catch, and so on.

I think that ozo should be more strict with the behavior that it accepts from customization points. Given that ozo is a boost::asio library, once control passes into boost::asio's main loop, throwing an exception is likely to cause major problems.

E.g. send_impl specialization throwing is something that a program cannot recover from, practically speaking. So it should be noexcept only.

In this way, ozo can then mark parts of itself noexcept where that makes sense, and that will allow consumers of the ozo API to have an easier time managing control flow / try-catch.

jonesmz commented 4 years ago

Another option that is significantly more work is to use the noexcept(noexcept(list-of-function-calls-here)) logic that can calculate whether a particular customization point is marked as noexcept by the caller at compile time.

I'm not suggesting that you do that, it honestly doesn't seem like it would be worth it, since just declaring functions as noexcept, or not-noexcept is likely to be what makes sense.

But it is something that could be done.

thed636 commented 4 years ago

In general, you right. But the problem is much deeper than the noexcept specification. I'll return in a couple of days with a more detailed reply for you. Thanks for your attention to this problem.

jonesmz commented 4 years ago

@thed636 Have you had any time to consider this?

thed636 commented 4 years ago

Hi Michael!

Sorry for so long silence. Haven't had enough time yet. :(