Changelog
Every released version of Errium.
The format follows Keep a Changelog, and the project adheres to Semantic Versioning.
0.2.0 — 2026-10-16
Found by an outside-in black-box test of 0.1.2 (17 findings). This release adds
new code values, so clients that switch exhaustively on code should handle
them.
Fixed
- The error path can no longer raise. An exception whose
__str__or__repr__fails, or whose arguments are unprintable, now produces the standard envelope on every adapter. A last-resort handler returns a genericINTERNAL_SERVER_ERRORwith a freshtrace_idif classification or formatting itself fails. - FastAPI:
HTTPException, unknown-route 404, 405 and body-parse 400 responses are now Errium envelopes instead of raw{"detail": ...}, andHTTPException(500, "secret")no longer leaks its message in production. - Ninja: a bare pydantic
ValidationErrorfrom a view — typically aresponse=schema mismatch — is now a 500 instead of a 422. - Django-native exceptions are classified on Ninja and DRF instead of collapsing
to 500:
PermissionDenied403,SuspiciousOperation400,RequestDataTooBig413, DjangoValidationError422/400,ObjectDoesNotExist404. - Flask no longer drops
Retry-AfterandAllow.
Changed
codenow matchesstatus_codefor HTTP errors: 400BAD_REQUEST, 405METHOD_NOT_ALLOWED, 406NOT_ACCEPTABLE, 408/504TIMEOUT, 409CONFLICT, 410GONE, 413PAYLOAD_TOO_LARGE, 415UNSUPPORTED_MEDIA_TYPE, 429RATE_LIMITED, 502/503SERVICE_UNAVAILABLE; any other 4xx isBAD_REQUEST. A plain HTTP 409 isCONFLICT; a database uniqueness violation is stillDUPLICATE_RESOURCE.- In production, 502/503/504 keep their code with a generic message; every other
5xx still collapses to
INTERNAL_SERVER_ERROR, and no 5xx carriesdetails. - A body that is not parseable JSON is
400 BAD_REQUESTon every adapter (FastAPI used to answer 422). - Response sizes are bounded:
detailsto 50 entries (with_truncated),debug.messageto 2,000 characters,debug.stack_traceto 20,000. Debug output for validation errors no longer echoes the requestinput. - Breaking for some clients: DRF
detailsuses the key_instead ofnon_field_errors, and joins several messages for one field with"; ". ERRIUM_DEBUGacceptsonand ignores surrounding whitespace; the mode is logged at import.
Added
errium.install(app)for FastAPI, anderrium.handlers.http_handler.- Logging of every handled exception on the
erriumlogger, anX-Trace-Idheader,request.state.errium_trace_id/flask.g.errium_trace_id/request.errium_trace_id/current_trace_id(), andERRIUM_TRUST_REQUEST_ID. - Protocol headers (
Allow,Retry-After,WWW-Authenticate,Location,Content-Range) are preserved on error responses. - The
errium_djangopackage —handler400/403/404/500andErriumDjangoMiddleware— and adjangoextra. - Database classification for Django’s ORM,
sqlite3,psycopg,psycopg2,asyncpgandpymysql. - Public classifier registration:
errium.register(...), andclassifiers=/engine=on every adapter,make_exception_handler()andsettings.ERRIUM["CLASSIFIERS"]for DRF. __version__on every package; theFramework :: Djangoclassifier.
0.1.2 — 2026-09-15
A documentation-only release. No code changes; published so the new documentation site is linked from the PyPI project page, which snapshots project metadata and the README per version.
Changed
- Documentation moved to this site. The
HomepageandDocumentationproject URLs now point here instead of at the previous MkDocs site on GitHub Pages, and the README links here. - The MkDocs site at
dagin34.github.io/erriumis retired. It now serves only a notice pointing to the new domain.
0.1.1 — 2026-09-03
A documentation-only release. No code changes; published so the updated README renders on the PyPI project page, which snapshots it per version.
Changed
- The README gained PyPI, Python version, licence and CI badges; documents the
flask,ninjaanddrfextras together; notes the shippedpy.typedmarkers; and flags that a server (uvicorn) must be installed separately, since Errium depends onfastapirather thanfastapi[standard].
Added
- A changelog.
0.1.0 — 2026-09-03
First public release, published on PyPI.
Added
- Core pipeline (
errium_core) — the framework-agnosticClassificationEngine, theExceptionClassifierprotocol, theClassifiedError/StandardizedErrorcontracts,DefaultFormatterandValidationNormalizer. Framework and SQLAlchemy exception types are detected by duck-typing rather than importing them, so the core stays dependency-light. - FastAPI adapter (
errium) —ErriumMiddlewarefor uncaught and HTTP exceptions, plusvalidation_exception_handlerforRequestValidationErrorwith beautifieddetails. - Flask adapter (
errium_flask) — theErriumFlaskextension, covering Werkzeug HTTP exceptions, uncaught exceptions, and pydantic validation errors raised inside views. - Django Ninja adapter (
errium_ninja) —register_errium(api), overriding Ninja’s built-in handlers forValidationError,HttpError,Http404andException. - Django REST Framework adapter (
errium_drf) —errium_exception_handler, wired throughREST_FRAMEWORK["EXCEPTION_HANDLER"], with its ownflatten_drf_errorsnormalizer. - Database classification —
DatabaseExceptionClassifiermaps SQLAlchemy errors toDATABASE_ERROR, and uniqueness violations toDUPLICATE_RESOURCE, with no hard SQLAlchemy dependency. - Dev vs. prod sanitization —
ERRIUM_DEBUGcontrols whether 5xx responses are sanitized and whether adebugblock with the stack trace and hints is attached. - Typing — all five packages ship a
py.typedmarker; the source is checked undermypy --strict.
Errium is MIT licensed.