Errium – Intelligent API Error Normalization for FastAPI
Errium is a lightweight, framework-agnostic error normalization and translation middleware for modern APIs. It intercepts uncaught exceptions, HTTP exceptions, and request validation errors, standardizing them into clean, consistent, and frontend-safe JSON responses.
📖 Read the documentation → errium.dagmawi.et — installation, per-framework guides, core concepts, and architecture.
⚡ The Problem
Building APIs with modern frameworks (like FastAPI) often yields inconsistent error responses, causing friction for frontend teams:
- Ugly FastAPI Validation Errors: Deeply nested, verbose, and difficult to parse direct Pydantic formats.
- Inconsistent Backend Responses: Uncaught internal exceptions return unhandled stack trace leaks or plain text errors depending on where they occurred.
- Frontend Integration Pain: Frontend engineers are forced to write custom parsers for every microservice, parsing varying response layouts.
🚀 The Solution
Errium provides a unified error classification, normalization, and formatting pipeline:
- Intelligent Middleware (
ErriumMiddleware): Transparently intercepts all request lifecycles. - Classification Engine (
ClassificationEngine): Dynamically resolves error categories, status codes, and user-facing messages. - Beautification & Normalization: Transforms nested, complex errors into flat, friendly key-value details.
- Environment-Aware Sanitization: Exposes detailed backtrace logs in
developmentand secures system internals inproduction.
🌟 Features
- 🟢 Unified Error Format: Every single API error response uses the exact same structured JSON contract.
- 💅 Validation Beautifier: Automatically maps common validation types (e.g.
missing, invalid emails, nulls) into clean, capitalized localized messages. - 🆔 Trace IDs: Seamlessly correlates client-facing responses with server-side application logs.
- 🛡️ Dev vs. Prod Mode: Exposes traceback objects, raw exception names, and actionable debug hints in development, while sanitizing server details in production.
- 🔌 Extensible Plugin Classifier: Register custom classifiers with sorting priority evaluation.
📦 Installation
Errium is published on PyPI and requires Python 3.11+.
uv pip install errium
# Or using traditional pip
pip install errium
The base install ships the core plus the FastAPI adapter. Each other framework is an extra:
uv pip install "errium[flask]" # Flask
uv pip install "errium[ninja]" # Django Ninja
uv pip install "errium[drf]" # Django REST Framework
Note: Errium depends on
fastapi, notfastapi[standard], so it stays light for Flask and Django users. If you were relying on Errium to pull in a server, install one yourself (uv pip install uvicorn).
All five packages ship a py.typed marker, so type checkers see Errium's annotations directly.
🛠️ Usage Example
Integrating Errium into your FastAPI codebase takes less than two lines:
from fastapi import FastAPI
from fastapi.exceptions import RequestValidationError
from errium import ErriumMiddleware
from errium.handlers.validation_handler import validation_exception_handler
app = FastAPI()
# 1. Add Middleware to catch raw & HTTP exceptions
app.add_middleware(ErriumMiddleware)
# 2. Add validation exception handler to capture validation errors
app.add_exception_handler(RequestValidationError, validation_exception_handler)
# Your endpoints go here...
Flask is supported too, via the errium[flask] extra:
uv pip install "errium[flask]"
from flask import Flask
from errium_flask import ErriumFlask
app = Flask(__name__)
# Registers a single catch-all error handler covering HTTP exceptions,
# uncaught exceptions, and pydantic validation errors.
ErriumFlask(app)
# Your routes go here...
Django Ninja is supported too, via the errium[ninja] extra:
uv pip install "errium[ninja]"
from ninja import NinjaAPI
from errium_ninja import register_errium
api = NinjaAPI()
# Registers handlers covering Ninja's ValidationError, HttpError (and its
# AuthenticationError/AuthorizationError/Throttled subclasses), Django's
# Http404, and generic exceptions.
register_errium(api)
# Your endpoints go here...
Django REST Framework is supported too, via the errium[drf] extra:
uv pip install "errium[drf]"
# settings.py
REST_FRAMEWORK = {
"EXCEPTION_HANDLER": "errium_drf.errium_exception_handler",
}
That's it — every exception raised inside a DRF view (APIException family, Django's Http404/
PermissionDenied, and any other uncaught exception) now returns Errium's standardized response.
Note: validation errors keep DRF's own 400 status code rather than the 422 the other adapters
use, matching DRF's established convention.
🔍 Before vs. After
❌ Before Errium (Ugly FastAPI Validation)
{
"detail": [
{
"type": "missing",
"loc": [
"body",
"password"
],
"msg": "Field required",
"input": null
}
]
}
After Errium (Cleaned, Beautified Response)
{
"success": false,
"status_code": 422,
"code": "VALIDATION_ERROR",
"message": "Validation failed.",
"trace_id": "87b003a8-7c15-4a6c-9c76-a05b22b109e2",
"timestamp": "2026-05-27T12:00:00Z",
"details": {
"password": "Password is required."
}
}
🗺️ Roadmap
Errium is designed framework-agnostically at the core. We are planning the following integrations:
- Flask Adapter Layer
- Django Ninja Adapter Layer
- Django REST Framework Adapter Layer
- Express.js Adapter Layer (JavaScript port)
- AI-Powered Developer Suggestions & Self-Healing Hints
See the roadmap (or ROADMAP.md) for more detail on what's
done and what's planned.
Metadata
Release files for errium 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| errium-0.1.2.tar.gz | 133.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| errium-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 158.6 kB
Release files / errium-0.1.2.tar.gz
| Download URL | errium-0.1.2.tar.gz |
|---|---|
| Size | 133.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
58790e216ec20b20939a2541f5cecd3786dba609b9add6aeef4f643f2fd5c26b
|
|
BLAKE2b-256 checksum How to use checksums |
2d6fa3ab89c0b9445952ba176f55e2aa316034e7dba5f48dd817b4eb9149c173
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / errium-0.1.2-py3-none-any.whl
| Download URL | errium-0.1.2-py3-none-any.whl |
|---|---|
| Size | 25.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b3539d22570606ac0bc831e0ba92c2d272da123e466f8bb289c73e8b9f72b1e4
|
|
BLAKE2b-256 checksum How to use checksums |
1888d4cef1864139f79044d3d04354130fc40a224d0e9bc41ca240ec2743f1b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|