From c94c433a5d8e5223b8bb3c6c9f1c5a837d6a414a Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Thu, 12 Jan 2023 15:41:43 +0000 Subject: [PATCH] Replace H2 with paragraphs and add section about examples --- google/cloud/doc/error-handling.dox | 61 +++++++++++++++++++---------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/google/cloud/doc/error-handling.dox b/google/cloud/doc/error-handling.dox index b34088506b45..674228c0ccc4 100644 --- a/google/cloud/doc/error-handling.dox +++ b/google/cloud/doc/error-handling.dox @@ -11,10 +11,10 @@ [input iterators]: https://en.cppreference.com/w/cpp/named_req/InputIterator [iostream operator<<]: @ref google::cloud::operator<<(std::ostream&,google::cloud::Status const&) -## Overview +@par Overview In general, the `google-cloud-cpp` libraries return a [StatusOr] if a -function many fail and needs to signal an error. `StatusOr` is an "outcome", +function may fail and needs to signal an error. `StatusOr` is an "outcome", it contains either the value returned on success, or a description of the error. Errors are represented by @ref google::cloud::Status, thus the name. If you are familiar with `std::expected` from C++23, `StatusOr` plays a @@ -25,18 +25,18 @@ A `Status` contains more than just the message, in particular, its [error_info()] member function may return additional information that is useful during troubleshooting. -## Values with specific error handling +@par Stream Ranges -Some functions return a value that already has a mechanism to signal failures. -For example, some functions return [AsyncStreamingReadWriteRpc] (or -technically `std::unique_ptr>`), and other -functions return classes derived from `std::istream`. In such -cases the library does not wrap the result in a `StatusOr` because the -returned type already has mechanisms to signal errors. +Some functions return [StreamRange], where `S` is a `StatusOr`. These +ranges provide [input iterators] that paginate or stream results from a service, +offering a more idiomatic API. The value type in these iterators is +`StatusOr` because the stream may fail after it has successfully returned +some values. For example, if the request to obtain the next page of results +fails, or if the underlying stream is interrupted by the service. -## Futures +@par Futures -Some functions return a "future" ([future]). This objects represent a value +Some functions return a "future" ([future]). These objects represent a value that will be obtained asynchronously. By the very nature of asynchronous operations, the request may fail after the function is called. Therefore, we have chosen to return `future>`. We think the alternatives are @@ -44,16 +44,16 @@ either incorrect (e.g. `StatusOr>` can only handle errors detected before the function returns), or overly complex (`StatusOr>>`). -## Stream Ranges +@par Values with specific error handling -Similarly, some functions return [StreamRange], where `S` is a `StatusOr`. -These ranges provide [input iterators] that paginate or stream results from a -service, offering a more idiomatic API. The value type in these iterators is -`StatusOr` because the stream may fail after it has successfully returned -some values. For example, if the request to obtain the next page of results -fails, or if the underlying stream is interrupted by the service. +Some functions return a value that already has a mechanism to signal failures. +For example, some functions return [AsyncStreamingReadWriteRpc] (or +technically `std::unique_ptr>`). A small number +of functions return classes derived from `std::istream` or `std::ostream. +In such cases, the library does not wrap the result in a `StatusOr` because +the returned type already has mechanisms to signal errors. -## Example: Using StatusOr +@par Example: Using StatusOr You can check that a `StatusOr` contains a value by calling the `.ok()` method, or by using `operator bool()` (like with other smart pointers). If @@ -65,7 +65,7 @@ accessing the contained value. @snippet samples.cc status-or-usage -## Example: Using StatusOr with exceptions +@par Example: Using StatusOr with exceptions Some applications prefer to throw exceptions on errors. In this case, consider using [StatusOr::value()]. This function throws a [RuntimeStatusError] if @@ -77,6 +77,27 @@ instead of throwing. @snippet samples.cc status-or-exceptions +@par Error Handling in google-cloud-cpp code samples + +The code samples for `google-cloud-cpp` try to emphasize how to use specific +APIs and often have minimal error handling. A typical code sample may simply +throw the status on error, like so: + +@code {.cpp} +namespace svc = ::google::cloud::some_service; +[](svc::Client client, std::string const& key) { + auto response = client.SomeRpc(key); + if (!response) throw std::move(response).status(); + // ... example continues here ... +} +@endcode + +This should not be interpreted as a best practice. If your application is +designed to work with exceptions, then using [StatusOr::value()] is a better +alternative. We just want to show that some error handling is required for these +functions, but at the same time we don't want to obscure the example with a lot +of error handling code. + @see @ref google::cloud::StatusOr @see @ref google::cloud::Status the class used to describe errors. @see @ref google::cloud::future for more details on the type returned