Skip to content

Exceptions

Every exception GFFBase raises, and what it means.

Most of these subclass ValueError rather than Exception, which is a deliberate departure from gffutils. Upstream exports DuplicateIDError and documents it, but the code path that should raise it raises a bare ValueError("Duplicate ID …") instead — so real callers in the wild write except ValueError. Making the dedicated classes also ValueError satisfies those callers and the documented type at once, instead of forcing a choice between compatibility and correctness.

FeatureNotFoundError is deliberately not rebased: it comes out of __getitem__, where callers reach for KeyError-shaped handling.

Exception Raised when
GFFFormatError A line violates the GFF3 specification. Carries line_no, kind and message, so you get a pointer into the file rather than a stack trace. When the Rust extension is loaded this is the PyO3-defined class; gffbase.GFFFormatError is rebound at import so isinstance works either way.
FeatureNotFoundError db[feature_id] and the id is not in the database.
DuplicateIDError Two features resolve to the same primary key under merge_strategy="error" (the default). Usually the split-CDS convention — see Modes.
AttributeStringError Column 9 is malformed beyond parsing.
EmptyInputError The input file or iterable yielded no features.
SchemaVersionError The database was written by a newer GFFBase, or its meta.schema_version is unintelligible, or it is a v1 database opened with upgrade="error". An older readable version is not an error — it degrades to compatibility mode.
MultipartConstraintError Under mode="strict", lines sharing an ID disagree on seqid, source, featuretype or strand, so they cannot be one discontinuous feature. Pass on_multipart_conflict="split" to partition them instead.
ReadOnlyError A write was attempted on a handle opened with read_only=True. See Connections & concurrency.
ClosedDatabaseError A FeatureDB was used after close(). Raised in place of DuckDB's ConnectionException, which says a connection is closed without saying which object or which call.
ValidationError Raised by validate_db(..., raise_on_error=True). Subclasses AssertionError.

Exception classes — verbatim port of legacy gffutils.exceptions.

Same names, same constructors, same attributes. Downstream code that catches gffutils.FeatureNotFoundError works against gffbase.FeatureNotFoundError.

GFFFormatError

GFFFormatError(message: str = '', *, line_no: int = 0, kind: str = '')

Bases: ValueError

Raised when a GFF3 line violates the spec.

Inherits from ValueError so legacy code that catches ValueError keeps working — but the dedicated subclass carries structured fields line_no, kind, and message that point callers straight to the offender in the input.

When the Rust extension is loaded, the canonical class is gffbase._native.GFFFormatError (a PyO3 create_exception! type). At import time, gffbase.__init__ rebinds the public name to whichever class is actually live so isinstance and except clauses keep working regardless of which path raised.

Source code in python/gffbase/exceptions.py
def __init__(self, message: str = "", *, line_no: int = 0, kind: str = ""):
    super().__init__(message)
    self.message = message
    self.line_no = line_no
    self.kind = kind

FeatureNotFoundError

FeatureNotFoundError(feature_id: str)

Bases: Exception

Raised by FeatureDB.__getitem__ when the requested ID is absent.

Source code in python/gffbase/exceptions.py
def __init__(self, feature_id: str):
    Exception.__init__(self, f"feature not found: {feature_id}")
    self.feature_id = feature_id

DuplicateIDError

Bases: ValueError

Two features resolved to the same primary key.

Raised during ingestion under merge_strategy="error" (the default).

AttributeStringError

Bases: ValueError

Raised on malformed col-9 attributes.

EmptyInputError

Bases: ValueError

Raised when an input file or iterable yields no features.

SchemaVersionError

Bases: ValueError

The database's schema version is one this build cannot read.

Raised when opening a database written by a newer gffbase, or one whose meta.schema_version is unintelligible. An older version is not an error: it degrades to a read-only compatibility mode instead.

This exists because the version was previously written and never read, so a schema mismatch surfaced as a missing-column error from whichever query happened to run first -- or, worse, as a silently wrong answer from one that did not touch the new columns.

MultipartConstraintError

Bases: ValueError

Lines sharing one ID cannot be one discontinuous feature.

GFF3 requires the segments of a discontinuous feature to agree on seqid, source, featuretype and strand. Raised in mode="strict" when they do not; pass on_multipart_conflict="split" to partition them instead.

ReadOnlyError

Bases: ValueError

A write was attempted on a database opened with read_only=True.

ClosedDatabaseError

Bases: ValueError

A FeatureDB was used after close().

Raised in place of DuckDB's own ConnectionException, which reports that a connection is closed without saying which object or which call.