Handle errors¶
Persistra uses a small exception hierarchy so callers can distinguish invalid normalized data, provider failures, cache problems, storage failures, and invalid analysis inputs.
Catch the narrowest useful exception¶
All library-specific exceptions inherit from PersistraError:
from persistra.errors import PersistraError
try:
result = run_research_operation()
except PersistraError as error:
record_failure(error)
For application behavior, catch a narrower class whenever the recovery path differs.
Understand the hierarchy¶
| Exception | Meaning | Typical response |
|---|---|---|
DataValidationError |
A normalized frame violates its exact contract | Reject the result and inspect construction or provider parsing |
AuthenticationError |
Provider credentials are missing or invalid | Correct credential configuration |
EntitlementError |
The provider account cannot access the operation | Change the request or account access |
RateLimitError |
Throttling exhausted bounded retries | Reduce request pressure or retry later |
ResponseError |
A provider payload is malformed or contradictory | Record operation context and inspect schema drift |
TransportError |
Network or transport retries were exhausted | Retry at the application boundary if appropriate |
NoDataError |
The provider explicitly reported no data | Treat absence according to the workflow |
CacheError |
Raw-cache access failed or offline content was absent | Fix cache access or populate the entry online |
StoreError |
Store creation, opening, encoding, or persistence failed | Preserve the original exception and inspect the database |
ProjectError |
A project manifest, path, name, or initialization operation is invalid | Correct the explicit target or manifest and retry |
AnalysisError |
Inputs violate a calculation's assumptions | Correct the dataset or choose another calculation |
Provider-specific exceptions inherit from ProviderError, which itself inherits from
PersistraError.
Separate no data from provider failure¶
from persistra.errors import NoDataError, ProviderError
try:
chain = client.options.historical_chain("IBM", date="2025-01-18")
except NoDataError:
chain = None
except ProviderError as error:
raise RuntimeError("option provider request failed") from error
Only treat NoDataError as an empty result when that meaning is valid for the task. Do not
convert authentication, entitlement, rate-limit, transport, or schema failures into empty
data.
The historical-chain range iterator already skips unambiguous no-data days. Direct calls do not hide the exception.
Handle offline cache misses¶
from persistra.errors import CacheError
from persistra.model import InstrumentKind
try:
bars = client.securities.bars(
"IBM",
kind=InstrumentKind.EQUITY,
interval="daily",
offline=True,
)
except CacheError as error:
raise RuntimeError("populate the daily IBM cache before offline use") from error
Do not retry the same offline call repeatedly. Either populate the exact cache key during an
authorized online phase or use synthetic data for a network-independent workflow.
Alpha Vantage and FRED both report this condition as CacheError; no network transport was
attempted.
Report schema diagnostics without treating them as errors¶
Unknown provider fields can be nonfatal when required values still normalize safely:
Use strict_schema=True on AlphaVantageClient or FredClient when any unknown field should
fail the request. Missing required fields and malformed values fail regardless of this
setting.
Add context without losing the original failure¶
Use exception chaining:
from persistra.errors import StoreError
try:
with DuckDBStore.open("research.duckdb") as store:
store.save(bars)
except StoreError as error:
raise RuntimeError("could not update the daily-bar research store") from error
Never include API keys, raw response bodies, or licensed observations in user-facing error messages. Operation names, symbols, intervals, exception types, and redacted diagnostic fields are usually enough to locate the failure.
Distinguish parameter errors¶
Invalid caller parameters often raise standard ValueError or TypeError before a provider
or store operation begins. Examples include an unsupported interval, a naive
retrieved_before value, an invalid option strike range, or a nonpositive analysis window.
Validate dynamic user input near the interface that accepts it. Programming errors in fixed configuration should normally propagate during development rather than being grouped with runtime provider failures.