Hi -
Actually, we have discussed this before, in another thread. You appear to disagree with our choice to report errors via exceptions. That is fine, and you are not the only one to dislike exceptions. You are welcome to wrap our API, catch exceptions, and report them via std::error_code or a similar convention in your code. Had we written an API that returned error codes instead of exceptions, someone preferring exceptions would have found that choice distasteful as well.
To your question about why some of these functions both return a result and throw an exception, the answer is that these methods do in fact return something - an object from the mongocxx::result namespace that describes the result of the database operation, assuming that it did not fail and raise an exception. This in fact is one of the things that pushed us towards using exceptions: had we not done so, the return slot would have been consumed by the error reporting object, and we would have been required to either:
- Return 'fat' results that contained both successful operation results and error codes, only some subset of which fields would have been valid or meaningful for any one operation.
- Return a std::tuple, std::pair, or something more like the proposed std::expected or Variant/Either type containing both/either the result and/or the error.
- Use out parameters for the database results.
None of these seemed like a better choice than simply using exceptions, which have the added benefit that users are forced to deal with them due to the non-local flow of control they impose. Error returns can be ignored.
Finally, you ask why the return value is an optional object. We return an optional object because in some write concern modes (notable w:0 a.k.a unacknowledged mode) the database does not return a result. By returning an optional result, we can model that situation. In practice, the C++11 driver does not currently do this, because of a bug in the underlying C driver (see
https://jira.mongodb.org/browse/CXX-894). When that bug is fixed, the C++11 driver will sometimes return disengaged optional results.
I'm happy to provide more details on any of the above points if you are curious.
Thanks,
Andrew