Skip to content

Error Handling

Exception Hierarchy

HIPO uses a modern C++ exception hierarchy based on std::runtime_error:

namespace hipo {
    class file_error   : public std::runtime_error { ... };
    class schema_error : public std::runtime_error { ... };
    class record_error : public std::runtime_error { ... };
}

All exceptions are defined in hipo4/hipoexceptions.h.

hipo::file_error

Thrown for file I/O errors:

  • File not found or cannot be opened
  • Corrupt file header
  • Invalid magic number
  • Read errors during dictionary or index parsing
try {
    reader.open("nonexistent.hipo");
} catch (const hipo::file_error& e) {
    fprintf(stderr, "File error: %s\n", e.what());
}

hipo::schema_error

Thrown when a requested schema does not exist:

try {
    auto& schema = dict.getSchema("NONEXISTENT::Bank");
} catch (const hipo::schema_error& e) {
    fprintf(stderr, "Schema error: %s\n", e.what());
}

Tip

Use dict.hasSchema(name) to check before calling getSchema() to avoid exceptions in expected cases.

hipo::record_error

Thrown for record-level errors:

  • LZ4 decompression failures
  • Corrupt record headers

Safe Patterns

Check Before Access

// Check schema existence
if (dict.hasSchema("REC::Particle")) {
    hipo::bank particles(dict.getSchema("REC::Particle"));
}

// Check column existence
if (schema.exists("pid")) {
    int col = schema.getEntryOrder("pid");
}

// Check row count (0 = bank not in event)
event.read(particles);
if (particles.getRows() > 0) {
    // safe to access
}

getEntryOrder Returns -1

When a column name is not found, getEntryOrder() returns -1 instead of throwing:

int col = schema.getEntryOrder("nonexistent");
if (col < 0) {
    // column not found
}

Common Error Scenarios

Scenario Behavior
Open nonexistent file hipo::file_error thrown
Get nonexistent schema hipo::schema_error thrown
Read bank not in event bank.getRows() returns 0
Access column by wrong name getEntryOrder() returns -1
Access row out of bounds Undefined behavior (no bounds check)
Write without closing File trailer not written, file may be unreadable

No Bounds Checking

Bank accessors (getInt, getFloat, etc.) do not check row or column bounds for performance. Accessing out-of-bounds indices is undefined behavior.