Error Handling

In general, the library returns a StatusOr. 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 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.

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).

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";
}

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.

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";
}