/**

@page storage-error Error Handling

[StatusOr<T>]: @ref google::cloud::StatusOr
[RuntimeStatusError]: @ref google::cloud::RuntimeStatusError

This library never throws exceptions to signal errors. In general, the library
returns a [StatusOr<T>]. Some functions return objects that
already have an existing error handling mechanism. For example, `ReadObject()`
returns a type derived from `std::istream` where the application can check the
[state flags](https://en.cppreference.com/w/cpp/io/basic_ios/rdstate)
to determine if there was an error. In these cases no `StatusOr` wrapper is
used.

Applications should check if the `StatusOr<T>` contains a value before using
it, much like how you might check that a pointer is not null before
dereferencing it. Indeed, a `StatusOr<T>` object can be used like a
smart-pointer to `T`, with the main difference being that when it does not hold
a `T` it will instead hold a `Status` object with extra information about the
error.

You can check that a `StatusOr<T>` contains a value by calling the `.ok()`
method, or by using `operator bool()` (like with other smart pointers). If
there is no value, you can access the contained `Status` object using the
`.status()` member. If there is a value, you may access it by dereferencing
with `operator*()` or `operator->()`. As with all smart pointers, callers must
first check that the `StatusOr<T>` contains a value before dereferencing and
accessing the contained value. Alternatively, callers may instead use the
`.value()` member function which is defined to throw a [RuntimeStatusError] if
there is no value.

@section storage-error-example Error Handling Example (without exceptions)

Applications that do not use exceptions to signal errors should check if the
`StatusOr<T>` contains a value before using it. If the `StatusOr<T>` does
contain a value then the `StatusOr<T>` can be used as a smart pointer to `T`.
That is, `operator->()` and `operator*()` work as you would expect. If the
`StatusOr<T>` does not contain a value then the error details are available
using the `.status()` member function (and trying to access the value produces
undefined behavior).

@code {.cpp}
using gcs = ::google::cloud::storage;
[](gcs::Client client) {
  google::cloud::StatusOr<gcs::BucketMetadata> metadata =
    client.GetBucketMetadata("my-bucket");

  if (!metadata) {
    std::cerr << "GetBucketMetadata: " << metadata.status() << "\n";
    return;
  }

  // use `metadata` as a smart pointer to `BucketMetadata`
  std::cout << "The metadata for bucket " << metadata->name()
            << " is " << *metadata << "\n";
}
@endcode

@section storage-error-example-ex Error Handling Example (with exceptions)

Applications that use exceptions to signal errors can simply call `.value()` on
the `StatusOr<T>` object. This will return a `T` if the `StatusOr<T>` object
contains a value, and will otherwise throw an exception.

@code {.cpp}
using gcs = ::google::cloud::storage;
[](gcs::Client client) {
  gcs::BucketMetadata metadata = client.GetBucketMetadata(
        "my-bucket").value();  // throws on error
  std::cout << "The metadata for bucket " << metadata.name()
            << " is " << metadata << "\n";
}
@endcode

*/
