Repository navigation
Releases: topunix/django-explain-errors
Release list
v0.11.0
0.11.0
Added
EXPLAIN_ERRORS_RAG_EMBED_BASE_URLandEXPLAIN_ERRORS_RAG_EMBED_API_KEYsettings, so RAG embeddings can use a different provider than chat.- Local embeddings backend (
EXPLAIN_ERRORS_RAG_EMBED_BACKEND = "local") via the newlocal-embeddingsextra, withall-MiniLM-L6-v2as the default model. No embeddings API key needed. - Index metadata (backend, model, dimension), with a one-time warning and traceback-only fallback when the index doesn't match the current settings.
- Clear
EmbeddingsNotSupportedErrorwhen RAG is pointed at Anthropic, which has no embeddings endpoint. - README Privacy section documenting what is sent where, redaction behavior and limits, and telemetry.
- Manual real-embeddings workflow for verifying the local backend against a real model.
Changed
- An embeddings API key is now required when the embeddings base URL differs from the chat base URL. The chat key is never sent to a different host.
- README reorganized: features list, section order, and Anthropic RAG options.
Fixed
- Redactor now catches suffixed secret names (
SECRET_KEY,AWS_SECRET_ACCESS_KEY), quoted dict keys, whole quoted values, URL credentials, and common API key shapes. Non-secret Django settings likeAUTH_USER_MODELare never redacted. - Production Safety no longer claims local variables are sent.
- Test suite works with openai 3.x (httpx2).
v0.10.1
Fix: ExplainErrorsMiddleware now marks itself as a coroutine function on async chains. Previously, async-capable middleware above it (including CommonMiddleware and Django Debug Toolbar) ran in sync mode and received a coroutine, so every request failed under ASGI with a TypeError or AttributeError.
v0.10.0
Added
- EXPLAIN_ERRORS_DEDUP (default True): when an error identical to one already explained in this process occurs again, the earlier explanation is replayed instead of calling the model or using a throttle slot. Errors are identical when they share exception type, exception message, and innermost project line (file, line number, and that line's source text). The last 128 distinct errors are kept per worker (least recently used evicted first) and entries never expire on a timer. Set to False to explain every error.
Changed
- Internal refactor: process_exception is split into _build_prompt and _generate_explanation. No behavior change.
Fixed
- The async path (acall) no longer dispatches to a thread when DEBUG is False, so the middleware stays fully inert in production.
v0.9.3
v0.9.3
Documentation release. No code changes.
README
- Clarified what the eval harness measures (#69)
- Fixed relative links to
evals/README.mdandLICENSEso they resolve on PyPI
Evals docs
- Added a TL;DR, condensed the cost section, and moved methodology history to
evals/METHODOLOGY.md(#64) - Defined RAG-on, RAG-off, and the eval's purpose in the intro (#66)
- Clarified the chunking fallback and budget setting (#66)
- Tightened the opening sentence (#67)
Roadmap
- Added retrieval combinations and pinned-frame lookup (#68)
Contributor docs
- Added a commit identity rule to
CLAUDE.md(#65)
Full changelog: v0.9.2...v0.9.3
v0.9.2
CI and packaging only. No runtime changes.
- The test suite now runs against every supported Python and Django pair: Django 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1 across Python 3.9 to 3.13, each with and without the [rag] extra (38 jobs).
- Releases and pull requests now share a single test workflow, so the release gate runs exactly what every PR runs.
- Framework :: Django classifiers restored for 4.2 through 6.1, each backed by passing CI.
- README: added a supported Django versions badge.
v0.9.1
Fixes
- Remove temp index file when build_index fails
Tests
- RAG index build redacts secrets in stored chunk text
- RAG frame extraction excludes site-packages frames
- RAG query text is sanitized before embedding
Docs
- Rewrite README intro with image first and badges; re-capture debug page screenshot at legible width
- README: restore strong RAG recommendation in intro, drop duplicate local-dev note from Scope, drop redundant intro bullet, reorder intro bullets
- Remove obsolete design docs and their references
- Roadmap: add eval-fix-validity, editor-open-links, and retrieval anchoring (hybrid retrieval plan); remove shipped readme-intro-rewrite
v0.9.0
Added
- Copy button on each code block in the debug page explanation banner, so a suggested fix copies in one click. Uses the Clipboard API on secure contexts such as localhost, with a text-selection fallback when the dev server is reached over plain HTTP. Empty code blocks get no button.
Docs
- README intro now states that explanations cover what went wrong and how to fix it.
- Banner screenshot re-recorded to show the Copy button.
v0.8.0
What's new
Explanations on the debug page (on by default). When Django renders its
debug page for a 500, the explanation now appears in a banner directly under
the exception headline, in addition to stdout. Set
EXPLAIN_ERRORS_INJECT_DEBUG_PAGE = False to turn it off. It requires
EXPLAIN_ERRORS_PRESERVE_DEBUG_PAGE = True (the default). A custom
DEFAULT_EXCEPTION_REPORTER is never overridden; injection is skipped
instead. Any failure while building the banner leaves Django's normal debug
page untouched.
Formatted explanations on the debug page. Inline code, code blocks, bold,
and lists in the explanation render as formatted text instead of raw Markdown.
Right-to-left languages such as Hebrew and Arabic display right to left, with
code kept left to right.
New setting: EXPLAIN_ERRORS_PRINT_STDOUT (default True). Set it to
False to stop printing the explanation to stdout. Failure messages always
print. A startup warning is logged if the settings leave no place for the
explanation to appear.
Provider-neutral messages. Output and error messages no longer assume
OpenAI, since explanations can come from any OpenAI-compatible provider.
Upgrading
- The debug page looks different by default: a new section appears above the
request metadata table. If anything depends on the page's exact markup
(scrapers, screenshot tests), setEXPLAIN_ERRORS_INJECT_DEBUG_PAGE = False
or update it. - The stdout prefix changed from
Error Explanation by OpenAI:to
Error explanation (<model>):. Update any log filters that match the old
text.
v0.7.0
- Tracebacks are now trimmed by frame rather than by character count. Application frames are always kept, and library frames fill the remaining budget nearest the error. Previously a deep Django ORM stack could consume the entire budget, leaving no application code in the explanation prompt at all.
- The tail-slice fallback no longer depends on sys.exc_info(), which under a real ASGI server may not have been populated in the worker thread.
- README: an Evaluation section reporting measured results for whether RAG improves explanations, a clearer account of language support, and the redundant Example section removed.
v0.6.0
EXPLAIN_ERRORS_LANGUAGE writes explanation prose in a configured language, while exception names, identifiers, code, and tracebacks stay in English. Independent of Django's LANGUAGE_CODE.
The token ceiling scales automatically when a language is set, so explanations in languages that tokenize less efficiently aren't cut off. An explicit OPENAI_MAX_TOKENS still overrides it.
Package description updated; per-version Django classifiers removed pending a real test matrix.