How to Use absl::Status for Error Handling in C++: A Complete Guide
Use absl::Status to signal success or failure with error codes and messages, and absl::StatusOr<T> to return either a value or an error, enabling explicit, exception-free error handling in modern C++.
The Abseil C++ library provides robust error handling utilities through absl::Status and absl::StatusOr<T>, defined in absl/status/status.h and absl/status/statusor.h. These types implement a "return-error-or-value" pattern similar to Rust's Result<T, E>, allowing functions to communicate failures explicitly without throwing exceptions. Learning how to use absl::Status for error handling in C++ is essential for writing reliable, maintainable code that follows Google's internal standards and modern C++ best practices.
Understanding absl::Status
absl::Status is a lightweight object defined in absl/status/status.h that carries an error code (absl::StatusCode) and an optional message.
Success is represented by absl::OkStatus(), which carries the code kOk. The API exposes several key methods for inspecting state:
ok()– Returnstrueif the status represents success.code()– Retrieves theabsl::StatusCodeenum value.message()– Returns the associated error message string.AddSourceLocation()– Attaches source location information for debugging.
Because absl::Status is cheap to copy, it can be returned from any function that only needs to signal success or failure without carrying a value.
Returning Values with absl::StatusOr
When a function needs to return either a value or an error, use absl::StatusOr<T> from absl/status/statusor.h. This is a discriminated union that holds either a status or a value of type T.
The contract is strict: presence of a value ↔ ok() == true. When the operation succeeds, the object holds type T; otherwise, it holds a non-OK Status.
Key Accessors and Methods
ok()– Test whether the operation succeeded.status()– Retrieve the storedStatusobject.value()– Get the value or throwabsl::BadStatusOrAccess(if exceptions are enabled) if not ok.operator*andoperator->– Convenient value access after anok()check.value_or(default)– Returns the value or a supplied default if an error occurred.IgnoreError()– Silences "unused-status" warnings when intentionally discarding errors.
absl::StatusOr<T> is marked [[nodiscard]] (or ABSL_MUST_USE_RESULT in absl/base/attributes.h) to prevent accidental discarding of error information.
Implementation Details and Design Features
The Abseil implementation in absl/status/internal/statusor_internal.h provides several architectural optimizations:
Zero-allocation on success: When StatusOr<T> holds a value, the internal Status is stored in a small inline representation, avoiding heap allocation.
Source-location tracking: Both Status and StatusOr expose AddSourceLocation() and WithSourceLocation() so callers can attach call-site information for richer diagnostics.
Conversion flexibility: StatusOr provides converting constructors and assignments for compatible types, as well as in-place construction via std::in_place.
Thread-safe copying: The type is copyable and movable as long as T satisfies the corresponding operations.
Practical Code Examples
The following examples demonstrate common patterns for using absl::Status for error handling in C++:
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/log/log.h"
// A simple function that may fail.
absl::StatusOr<int> ParseInt(absl::string_view text) {
int value;
if (absl::SimpleAtoi(text, &value)) {
return value; // OK → holds an int.
}
return absl::InvalidArgumentError("not an integer");
}
// Consumer code
absl::StatusOr<int> result = ParseInt("42");
if (result.ok()) {
LOG(INFO) << "Parsed value: " << *result; // operator* after ok()
} else {
LOG(ERROR) << "Parse failed: " << result.status();
}
// Using value_or to provide a fallback.
int safe = ParseInt("abc").value_or(0);
LOG(INFO) << "Safe value = " << safe;
// Propagating errors with source locations.
absl::StatusOr<std::string> LoadFile(absl::string_view path) {
// ... file IO omitted ...
if (/*io error*/) {
return absl::NotFoundError("file not found")
.WithSourceLocation(); // attaches caller location
}
return std::string("file contents");
}
// Chaining calls
absl::StatusOr<std::string> content = LoadFile("data.txt")
.WithSourceLocation();
if (!content.ok()) return content.status(); // early return on error
Summary
absl::Statusprovides a lightweight, copyable error indicator with error codes and messages, usingabsl::OkStatus()for success.absl::StatusOr<T>wraps either a value or an error, enforcing explicit checking throughok()before access.- Key accessors include
value(),value_or(),status(), and dereference operators for safe value extraction. - Design optimizations include zero-allocation success paths, source location tracking, and
[[nodiscard]]enforcement to prevent silent error dropping. - Primary headers are
absl/status/status.handabsl/status/statusor.h, with internal implementation details inabsl/status/internal/statusor_internal.h.
Frequently Asked Questions
What is the difference between absl::Status and absl::StatusOr?
absl::Status signals success or failure without carrying a return value, similar to returning a boolean with extra error details. absl::StatusOr<T> is a discriminated union that contains either a value of type T on success or a non-OK status on failure. Use Status for void functions that might fail, and StatusOr<T> when you need to return data or an error.
How do I check if an absl::StatusOr contains a valid value?
Always call ok() before accessing the value. If ok() returns true, you can safely use operator*, operator->, or value() to retrieve the stored object. If ok() is false, calling value() will throw absl::BadStatusOrAccess when exceptions are enabled, or terminate the program if exceptions are disabled.
Can I attach source location information to errors?
Yes. Both absl::Status and absl::StatusOr provide WithSourceLocation() and AddSourceLocation() methods to attach call-site information. This is implemented in absl/status/status.h and helps developers trace where errors originated in the codebase.
Is absl::StatusOr efficient for large return types?
Yes. The implementation in absl/status/internal/statusor_internal.h uses inline storage for the internal Status representation when holding a value, achieving zero-allocation on success. For large types T, StatusOr moves or copies T according to standard C++ semantics, so returning by value is efficient due to move semantics and return value optimization (RVO).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →