Skip to main content

Overview

The Status class encapsulates the result of an operation. It may indicate success or an error with an associated error message. Multiple threads can invoke const methods on a Status without external synchronization.

Status Codes

Code Enum

enum Code : unsigned char {
  kOk = 0,
  kNotFound = 1,
  kCorruption = 2,
  kNotSupported = 3,
  kInvalidArgument = 4,
  kIOError = 5,
  kMergeInProgress = 6,
  kIncomplete = 7,
  kShutdownInProgress = 8,
  kTimedOut = 9,
  kAborted = 10,
  kBusy = 11,
  kExpired = 12,
  kTryAgain = 13,
  kCompactionTooLarge = 14,
  kColumnFamilyDropped = 15,
  kMaxCode
};

SubCode Enum

enum SubCode : unsigned char {
  kNone = 0,
  kMutexTimeout = 1,
  kLockTimeout = 2,
  kLockLimit = 3,
  kNoSpace = 4,
  kDeadlock = 5,
  kStaleFile = 6,
  kMemoryLimit = 7,
  kSpaceLimit = 8,
  kPathNotFound = 9,
  KMergeOperandsInsufficientCapacity = 10,
  kManualCompactionPaused = 11,
  kOverwritten = 12,
  kTxnNotPrepared = 13,
  kIOFenced = 14,
  kMergeOperatorFailed = 15,
  kMergeOperandThresholdExceeded = 16,
  kPrefetchLimitReached = 17,
  kNotExpectedCodePath = 18,
  kCompactionAborted = 19,
  kMaxSubCode
};

Severity Enum

enum Severity : unsigned char {
  kNoError = 0,
  kSoftError = 1,
  kHardError = 2,
  kFatalError = 3,
  kUnrecoverableError = 4,
  kMaxSeverity
};

Creating Status Objects

Success Status

static Status OK();
Status
Status
Returns a success status
Status s = Status::OK();
assert(s.ok());

Error Status Constructors

NotFound

static Status NotFound(const Slice& msg, const Slice& msg2 = Slice());
static Status NotFound(SubCode msg = kNone);
return Status::NotFound("Key not in database");
return Status::NotFound();  // Fast path without malloc

Corruption

static Status Corruption(const Slice& msg, const Slice& msg2 = Slice());
static Status Corruption(SubCode msg = kNone);
Indicates data corruption detected.

NotSupported

static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice());
static Status NotSupported(SubCode msg = kNone);
Operation is not supported by this implementation.

InvalidArgument

static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice());
static Status InvalidArgument(SubCode msg = kNone);
Invalid arguments provided to the operation.

IOError

static Status IOError(const Slice& msg, const Slice& msg2 = Slice());
static Status IOError(SubCode msg = kNone);
if (read_failed) {
  return Status::IOError("Failed to read file", filename);
}

Incomplete

static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice());
static Status Incomplete(SubCode msg = kNone);
Operation did not complete (e.g., compaction was aborted).

ShutdownInProgress

static Status ShutdownInProgress(SubCode msg = kNone);
static Status ShutdownInProgress(const Slice& msg, const Slice& msg2 = Slice());

Aborted

static Status Aborted(SubCode msg = kNone);
static Status Aborted(const Slice& msg, const Slice& msg2 = Slice());
Operation was aborted.

Busy

static Status Busy(SubCode msg = kNone);
static Status Busy(const Slice& msg, const Slice& msg2 = Slice());
Resource is busy and temporarily could not be acquired.

TimedOut

static Status TimedOut(SubCode msg = kNone);
static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice());

TryAgain

static Status TryAgain(SubCode msg = kNone);
static Status TryAgain(const Slice& msg, const Slice& msg2 = Slice());
Operation failed but may succeed if re-attempted.

Specialized Error Constructors

NoSpace

static Status NoSpace();
static Status NoSpace(const Slice& msg, const Slice& msg2 = Slice());
Out of disk space error (IOError with kNoSpace subcode).

MemoryLimit

static Status MemoryLimit();
static Status MemoryLimit(const Slice& msg, const Slice& msg2 = Slice());
Memory limit exceeded (Aborted with kMemoryLimit subcode).

SpaceLimit

static Status SpaceLimit();
static Status SpaceLimit(const Slice& msg, const Slice& msg2 = Slice());
Space limit exceeded (IOError with kSpaceLimit subcode).

PathNotFound

static Status PathNotFound();
static Status PathNotFound(const Slice& msg, const Slice& msg2 = Slice());
File or directory not found (IOError with kPathNotFound subcode).

Checking Status

ok

bool ok() const;
bool
bool
Returns true if the status indicates success
Status s = db->Get(read_options, key, &value);
if (s.ok()) {
  // Operation succeeded
} else {
  // Handle error
}

Error Type Checking

IsNotFound

bool IsNotFound() const;
Returns true if status indicates a NotFound error.
Status s = db->Get(read_options, "key", &value);
if (s.IsNotFound()) {
  // Key doesn't exist, this is expected
} else if (!s.ok()) {
  // Some other error occurred
}

IsCorruption

bool IsCorruption() const;
Returns true if status indicates a Corruption error.

IsNotSupported

bool IsNotSupported() const;
Returns true if status indicates a NotSupported error.

IsInvalidArgument

bool IsInvalidArgument() const;
Returns true if status indicates an InvalidArgument error.

IsIOError

bool IsIOError() const;
Returns true if status indicates an IOError.

IsIncomplete

bool IsIncomplete() const;
Returns true if status indicates Incomplete.

IsShutdownInProgress

bool IsShutdownInProgress() const;

IsTimedOut

bool IsTimedOut() const;

IsAborted

bool IsAborted() const;

IsBusy

bool IsBusy() const;

IsTryAgain

bool IsTryAgain() const;

Specialized Error Checking

IsNoSpace

bool IsNoSpace() const;
Returns true if status indicates an out-of-space I/O error.

IsMemoryLimit

bool IsMemoryLimit() const;
Returns true if status indicates memory limit error.

IsPathNotFound

bool IsPathNotFound() const;
Returns true if status indicates path not found error.

IsManualCompactionPaused

bool IsManualCompactionPaused() const;
Returns true if manual compaction was paused.

Accessing Status Information

code

Code code() const;
Code
Code
Returns the primary status code

subcode

SubCode subcode() const;
SubCode
SubCode
Returns the status subcode for additional error context

severity

Severity severity() const;
Severity
Severity
Returns the error severity level

getState

const char* getState() const;
const char*
const char*
Returns a C-style string containing the error message

ToString

std::string ToString() const;
std::string
std::string
Returns a string representation suitable for printing. Returns “OK” for success.
Status s = db->Put(write_options, key, value);
if (!s.ok()) {
  std::cerr << "Put failed: " << s.ToString() << std::endl;
}

Status Manipulation

UpdateIfOk

Status& UpdateIfOk(Status&& s);
Status& UpdateIfOk(const Status& s);
s
Status
Status to potentially adopt
Status&
Status&
Returns reference to this Status (allows chaining)
Override this status with another, unless this status is already non-ok. Left-most error takes precedence.
Status overall_status = Status::OK();
overall_status.UpdateIfOk(db->Put(options, "key1", "value1"))
              .UpdateIfOk(db->Put(options, "key2", "value2"))
              .UpdateIfOk(db->Put(options, "key3", "value3"));
// overall_status will be the first error encountered, or OK if all succeeded

CopyAppendMessage

static Status CopyAppendMessage(const Status& s, 
                                const Slice& delim,
                                const Slice& msg);
Create a new Status by appending additional message to an existing Status.

Unchecked Status Handling

PermitUncheckedError

inline void PermitUncheckedError() const;
Explicitly mark that you are intentionally ignoring this error. Makes it easy to search for error swallowing.
Status s = db->Delete(write_options, key);
if (s.IsNotFound()) {
  // Key didn't exist, that's fine
  s.PermitUncheckedError();
}
When ROCKSDB_ASSERT_STATUS_CHECKED is defined, Status objects must be checked before being destroyed, otherwise the program will abort.

Common Usage Patterns

Basic Error Handling

Status s = db->Get(read_options, key, &value);
if (!s.ok()) {
  if (s.IsNotFound()) {
    // Handle missing key
    return default_value;
  } else {
    // Handle other errors
    LOG(ERROR) << "Get failed: " << s.ToString();
    return s;
  }
}
// Use value

Multiple Operations

Status BatchWrite(DB* db, const std::vector<std::pair<std::string, std::string>>& kvs) {
  WriteBatch batch;
  for (const auto& kv : kvs) {
    batch.Put(kv.first, kv.second);
  }
  
  Status s = db->Write(WriteOptions(), &batch);
  if (!s.ok()) {
    LOG(ERROR) << "Batch write failed: " << s.ToString();
  }
  return s;
}

Accumulating Errors

Status ProcessRecords(DB* db) {
  Status result = Status::OK();
  
  result.UpdateIfOk(ProcessRecord1(db));
  result.UpdateIfOk(ProcessRecord2(db));
  result.UpdateIfOk(ProcessRecord3(db));
  
  // result contains first error, or OK if all succeeded
  return result;
}

Retrying on Specific Errors

Status WriteWithRetry(DB* db, const std::string& key, const std::string& value) {
  const int max_retries = 3;
  for (int i = 0; i < max_retries; i++) {
    Status s = db->Put(WriteOptions(), key, value);
    if (s.ok()) {
      return s;
    }
    if (s.IsBusy() || s.IsTryAgain()) {
      // Wait and retry
      std::this_thread::sleep_for(std::chrono::milliseconds(100 * (i + 1)));
      continue;
    }
    // Don't retry other errors
    return s;
  }
  return Status::TimedOut("Max retries exceeded");
}

Build docs developers (and LLMs) love