# Using absl::Status and absl::StatusOr for C++ Error Handling: A Complete Guide

> Master C++ error handling with absl::Status and absl::StatusOr. Learn to signal success or failure and return values or errors for robust applications. Optimize your code now.

- Repository: [Abseil/abseil-cpp](https://github.com/abseil/abseil-cpp)
- Tags: tutorial
- Published: 2026-07-16

---

**Use `absl::Status` to signal success or failure with error codes, and `absl::StatusOr<T>` to return either a value or an error, enabling explicit error handling without exceptions.**

The `absl::Status` and `absl::StatusOr<T>` utilities in the `abseil/abseil-cpp` repository provide a robust, exception-free mechanism for handling errors in modern C++. These types implement the "return-error-or-value" pattern popularized by Google's internal codebase, offering lightweight semantics that encourage explicit error checking while maintaining zero-overhead abstractions.

## Understanding absl::Status

In [`absl/status/status.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/status.h), `absl::Status` is implemented as a lightweight object that carries an `absl::StatusCode` and an optional message string. It serves as the fundamental currency for signaling operation success or failure throughout Abseil-based codebases.

### Core API and Success Semantics

Success is represented by `absl::OkStatus()`, which returns a status with code `kOk`. The class provides a mirror of `absl::StatusCode` semantics through key accessors:

- **`ok()`** – Returns `true` if the status code is `kOk`.
- **`code()`** – Retrieves the `absl::StatusCode` enum value.
- **`message()`** – Returns the error message string (empty for OK statuses).

The type is cheap to copy and can be returned from any function that only needs to signal success or failure without transporting a value.

### Source Location Tracking

Both `Status` and `StatusOr` expose `AddSourceLocation()` and `WithSourceLocation()` methods defined in [`absl/status/status.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/status.h). These allow callers to attach call-site information for richer diagnostics, particularly useful when propagating errors up the stack:

```cpp
return absl::NotFoundError("file not found")
    .WithSourceLocation();  // Attaches caller location automatically

```

## Understanding absl::StatusOr<T>

Defined in [`absl/status/statusor.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/statusor.h), `absl::StatusOr<T>` is a discriminated union that holds either a value of type `T` or a non-OK `Status`. This pattern eliminates the need for output parameters or exceptions when returning values that might fail to generate.

### Value vs. Error Contract

The fundamental contract is **presence of a value ↔ `ok() == true`**. When the operation succeeds, the object stores the constructed `T`; otherwise, it stores a `Status` indicating the error. The internal implementation in [`absl/status/internal/statusor_internal.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/internal/statusor_internal.h) manages this union efficiently, storing the `Status` inline to avoid heap allocation when holding a value.

### Accessing Values and Handling Errors

`StatusOr<T>` provides multiple accessors for safe value extraction:

- **`ok()`** – Tests whether the object contains a value.
- **`status()`** – Retrieves the stored `Status` (useful for error propagation).
- **`value()`** – Returns the value or throws `absl::BadStatusOrAccess` if exceptions are enabled and the status is not OK.
- **`operator*` / `operator->`** – Provide convenient value access after an `ok()` check.
- **`value_or(default)`** – Returns the contained value or a supplied default if the status is not OK.
- **`IgnoreError()`** – Silences "unused-status" warnings when the caller intentionally discards an error.

The type is marked with `ABSL_MUST_USE_RESULT` (expanding to `[[nodiscard]]` on supported compilers) in [`absl/base/attributes.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/base/attributes.h), preventing accidental discarding of error information.

## Key Architectural Features

The implementation provides several guarantees critical for high-performance C++:

**Zero-allocation on success** – When `StatusOr<T>` holds a value, the internal error storage is kept in a small inline representation, avoiding heap allocation entirely.

**Conversion flexibility** – The class 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, with no internal synchronization required.

## Practical Implementation Examples

The following patterns demonstrate idiomatic usage according to the `abseil/abseil-cpp` source:

```cpp
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/log/log.h"

// Returns either an int or an error
absl::StatusOr<int> ParseInt(absl::string_view text) {
  int value;
  if (absl::SimpleAtoi(text, &value)) {
    return value;  // Implicit construction from T
  }
  return absl::InvalidArgumentError("not an integer");
}

// Consumer code with explicit checking
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 for safe defaults
int safe = ParseInt("abc").value_or(0);

// Error propagation with source location
absl::StatusOr<std::string> LoadFile(absl::string_view path) {
  if (/* simulated IO error */ false) {
    return absl::NotFoundError("file not found")
        .WithSourceLocation();
  }
  return std::string("file contents");
}

// Chaining with early return
absl::StatusOr<std::string> content = LoadFile("data.txt");
if (!content.ok()) return content.status();  // Propagate error

```

## Summary

- **`absl::Status`** (in [`absl/status/status.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/status.h)) signals success/failure via error codes, with `absl::OkStatus()` representing success.
- **`absl::StatusOr<T>`** (in [`absl/status/statusor.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/statusor.h)) transports either a value or an error status,强制执行 explicit checking through `[[nodiscard]]` semantics.
- **Access values** using `ok()` followed by `operator*` or `operator->`, or use `value_or()` for default fallbacks.
- **Zero-allocation** guarantees and inline storage make `StatusOr` suitable for performance-critical paths.
- **Source location tracking** via `WithSourceLocation()` aids debugging without macro magic.

## Frequently Asked Questions

### What is the difference between absl::Status and absl::StatusOr<T>?

`absl::Status` only indicates success or failure via error codes and messages, while `absl::StatusOr<T>` is a discriminated union that either contains a value of type `T` or a non-OK status. Use `Status` for void functions that might fail, and `StatusOr` when you need to return a computed value or an error.

### How do I handle errors without exceptions using StatusOr?

Check `ok()` before accessing the value, or use `value_or()` to provide a default. For error propagation, call `status()` to extract the underlying `Status` and return it upstream. The `ABSL_MUST_USE_RESULT` attribute ensures the compiler warns you if you accidentally ignore a returned error.

### Does absl::StatusOr allocate memory on the heap?

No. The implementation uses inline storage for the `Status` object when a value is present, resulting in zero heap allocation on the success path. This is managed internally through the variant storage logic in [`absl/status/internal/statusor_internal.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/status/internal/statusor_internal.h).

### How do I attach source location information to errors?

Call `WithSourceLocation()` on any `absl::Status` or `absl::StatusOr` to automatically capture the current file and line number. This information is stored within the status object and can be logged or serialized for debugging distributed systems.