Exception Hierarchyο
siege_utilities follows a fail-loud-over-silent-swallow policy: when
a function cannot deliver its documented output, it raises a typed exception
rather than returning None, False, or an empty container that looks
like a legitimate βno result.β This distinguishes real failures from
expected empty-input paths and prevents silent data corruption in
downstream pipelines.
This page catalogs the typed exceptions across the library. Every exception
subclasses a standard Python exception (LookupError, ValueError,
RuntimeError) so broad existing handlers continue to work.
Design principlesο
Lookup failures are ``LookupError``. Missing chart types, missing client configs, and similar βyou asked for X but X doesnβt existβ cases.
Parameter / input failures are ``ValueError``. Missing required parameters, invalid values, bad config shapes.
Operation failures are ``RuntimeError``. Failed I/O, failed parse, failed API call β anything where the inputs were valid but the work did not complete.
Not-found return values are preserved where semantic.
list_X()returning[], lookup helpers returningNonewhen the caller should handle absence as normal β these are unchanged. The rewrite only affects sites where absence was masking a transport or parse failure.Every raise chains with ``from e``. Inspect
exc.__cause__to see the underlying error (JSONDecodeError,OSError,HTTPError, etc.).
Reportingο
Top-level config export / importο
Chart type registryο
Client brandingο
Geographicο
Census Bureau geocoderο
- exception siege_utilities.geo.census_geocoder.CensusGeocodeError[source]ο
Bases:
RuntimeErrorRaised when the Census geocoder API call fails unexpectedly.
Distinct from βno matchβ results (which return a CensusGeocodeResult with matched=False). This exception indicates an API / network / parse failure where the geocoder could not even attempt to match. Use __cause__ to inspect the underlying exception.
- __init__(*args, **kwargs)ο
- classmethod __new__(*args, **kwargs)ο
Before this change, geocode_single() and geocode_batch() caught all
failures (network, API, parse) and returned
CensusGeocodeResult(matched=False). Downstream pipelines treated
unmatched rows as βaddress not findableβ and dropped them β so API
outages silently poisoned entire batches with fake unmatched rows.
CensusGeocodeError surfaces the real cause.
Spatial data sourcesο
Used by GovernmentDataSource (CKAN-style portals) and
OpenStreetMapDataSource (Overpass API). Distinct from boundary
retrieval, which has its own hierarchy below.
Boundary retrievalο
- exception siege_utilities.geo.boundary_result.BoundaryRetrievalError[source]ο
Bases:
SiegeGeoErrorBase exception for all boundary retrieval failures.
Inherits from
SiegeGeoErrorso callers can catch the entire siege_utilities exception family with a singleexcept SiegeError:. Previously this stood alone outside the documented hierarchy and slipped pastexcept SiegeErrorblocks.- classmethod __new__(*args, **kwargs)ο
- exception siege_utilities.geo.boundary_result.BoundaryInputError[source]ο
Bases:
BoundaryRetrievalErrorInvalid input parameters (state FIPS, year, geographic level).
- classmethod __new__(*args, **kwargs)ο
- exception siege_utilities.geo.boundary_result.BoundaryDiscoveryError[source]ο
Bases:
BoundaryRetrievalErrorFailed to discover available boundary types or construct a URL.
- classmethod __new__(*args, **kwargs)ο
- exception siege_utilities.geo.boundary_result.BoundaryUrlValidationError[source]ο
Bases:
BoundaryRetrievalErrorConstructed URL is not accessible (HTTP error, timeout, etc.).
- classmethod __new__(*args, **kwargs)ο
- exception siege_utilities.geo.boundary_result.BoundaryDownloadError[source]ο
Bases:
BoundaryRetrievalErrorDownload succeeded but the file is corrupt or not a valid zip.
- classmethod __new__(*args, **kwargs)ο
- exception siege_utilities.geo.boundary_result.BoundaryParseError[source]ο
Bases:
BoundaryRetrievalErrorDownloaded data could not be parsed as a shapefile/GeoDataFrame.
- classmethod __new__(*args, **kwargs)ο
Migration guidanceο
Callers that relied on the pre-rewrite silent-swallow behavior must
migrate to try/except around the new exception types.
Before:
result = registry.create_chart("unknown_type")
if result is None:
log.warning("chart creation failed")
return None
After:
try:
result = registry.create_chart("unknown_type")
except UnknownChartTypeError:
log.warning("unknown chart type")
return None
except ChartCreationError as e:
log.error("chart creation failed: %s", e.__cause__)
raise
Because the exception types subclass standard Python exceptions, you can
also use a single broad except LookupError: / except ValueError: /
except RuntimeError: if you do not need to distinguish cases. The
__cause__ attribute still gives you the original error.
Further readingο
../../docs/FAILURE_MODES β complete anti-pattern catalog
../../docs/ARCHITECTURE β three-layer dependency model