askerror
Beautiful, contextual Python error explanations — offline, automatic, actionable.
Instead of a raw traceback:
AttributeError: 'NoneType' object has no attribute 'append'
askerror shows:
X AttributeError
'NoneType' object has no attribute 'append'
Location
File: app.py, line 42
In: process_data
Code: items.append("x")
Call Chain
-> main
app.py:55
-> process_data
app.py:42
Suggestion
* The value became None before calling .append
* Check if the previous operation returned None
* Add a guard: if value is not None: value.append(...)
Documentation
https://docs.python.org/3/library/exceptions.html#attributeerror
Features
| Feature | Description |
|---|---|
| Location | Relative file path, line number, function name, and the exact line of code |
| Call Chain | Visual call chain showing how the error propagated |
| Smart Suggestions | Rule-based suggestions per error type — no API key needed |
| Typo Detection | NameError suggests similar variable names using difflib |
| Environment Checks | Python version, virtual env detection for ModuleNotFoundError |
| Nearby Files | Lists nearby files when a FileNotFoundError occurs |
| CLI | askerror run, askerror doctor, askerror report |
| HTML Reports | Dark-themed HTML error reports with toggleable variable details |
| Decorator | @explain wraps individual functions |
| Zero Dependencies | Only rich (for terminal output) and easydotdict (for config) |
Installation
pip install askerror
Requires Python 3.8+.
Usage
Method 1 — Import and Install
import askerror
askerror.install()
Every uncaught exception from that point onward is formatted beautifully.
# examply.py
import askerror
askerror.install()
items = None
items.append("hello")
Run it:
python examply.py
Method 2 — Decorator
from askerror import explain
@explain
def main():
items = None
items.append("hello")
main()
Method 3 — CLI
Run any script with beautified errors:
askerror run app.py
askerror run app.py --arg1 value1
CLI Commands
askerror run <script> [args...]
Runs a Python script with askerror's exception hook enabled. All arguments after the script name are passed to the script as sys.argv.
askerror run server.py --port 8080
askerror doctor
Checks your Python environment:
- Python version
- Virtual environment status
richandeasydotdictinstallation- Config file status
askerror doctor
askerror report [--output file.html]
Displays the last error report and generates an HTML file with full details:
- Traceback with frames
- Local variables at each frame
- Suggestions
- Documentation links
askerror report --output crash.html
Error Types
AttributeError
When items is None and you call items.append(...):
Suggestion
* The value became None before calling .append
* Check if the previous operation returned None
* Add a guard: if value is not None: value.append(...)
NameError
When you mistype a variable name:
Suggestion
* Did you mean 'username'? Similarity: 88%
TypeError
len()on a non-sequence → shows what type you gave- Unsupported operand types → tells you they're incompatible
- Missing/extra function arguments → counts them
- Non-callable object → suggests you check parentheses
KeyError
When accessing a missing dictionary key:
Suggestion
* Available keys: id, email, created_at
* 'name' does not exist in the dictionary
IndexError
When accessing an index beyond the list length:
Suggestion
* List length: 5
* Valid indexes: 0-4
* Check that the list has enough elements before accessing
ModuleNotFoundError
When a module is not installed:
Suggestion
* 'pandas' is not installed.
* Run: pip install pandas
* Current Python: 3.12
* Virtual Environment: Yes
FileNotFoundError
When a file does not exist:
Suggestion
* Could not find: data.csv
* Looked in: /home/user/project
* Nearby files: database.csv, data.json, config.yaml
* Current Directory: /home/user/project
ValueError
int("abc")→ shows the invalid stringfloat("x")→ shows the invalid string- Unpacking mismatches → explains too few / too many values
ZeroDivisionError
When dividing by zero:
Suggestion
* Division or modulo by zero
* x became zero here: math.py:88
JSONDecodeError
When parsing invalid JSON:
Suggestion
* Invalid JSON
* Line 8
* Unexpected character — check for trailing commas
SyntaxError
When Python cannot parse your code:
Suggestion
* Missing ':' — did you forget a colon at the end of the line?
* Line 5
HTML Reports
Generate shareable HTML error reports:
from askerror.html import generate_html_report
report = {
"type_name": "AttributeError",
"message": "'NoneType' object has no attribute 'append'",
"traceback": {"frames": [...]},
"suggestions": ["..."],
}
html = generate_html_report(report)
with open("error.html", "w") as f:
f.write(html)
Or from the CLI:
askerror report --output error.html
Each HTML report includes:
- Error type and message
- Suggestions
- Frame-by-frame traceback (click to expand variables)
- Documentation link
- Dark theme (GitHub Dark style)
Configuration
Configuration is stored at ~/.askerror/config.json as a dotdict.
from askerror import config
config.ai.provider = "openai"
config.ai.api_key = "sk-..."
config.save()
| Key | Default | Description |
|---|---|---|
theme |
"auto" |
Color theme |
ai.enabled |
false |
Enable AI suggestions |
ai.provider |
null |
AI provider name |
ai.model |
null |
AI model name |
output.color |
true |
Colored terminal output |
output.html_reports |
true |
Enable HTML reports |
output.show_variables |
true |
Show variables in output |
Architecture
askerror/
├── askerror/
│ ├── __init__.py # Exports: install(), @explain, config
│ ├── main.py # Exception hook + @explain decorator
│ ├── config.py # dotdict-backed persistent config
│ ├── cli.py # CLI: run, doctor, report
│ ├── html.py # Dark-themed HTML report generator
│ ├── handlers/
│ │ ├── base.py # Rich panel renderer + sections
│ │ ├── attribute.py # NoneType / missing attribute
│ │ ├── type_.py # TypeError: len, callable, args
│ │ ├── key.py # KeyError + available keys
│ │ ├── index.py # IndexError + list length
│ │ ├── name.py # NameError + difflib suggestions
│ │ ├── module.py # ModuleNotFoundError + env info
│ │ ├── file.py # FileNotFoundError + nearby files
│ │ ├── json_error.py # JSONDecodeError + line/col
│ │ ├── value.py # ValueError: int/float parse
│ │ ├── zero.py # ZeroDivisionError
│ │ └── syntax.py # SyntaxError hints
│ └── analyzer/
│ ├── traceback.py # Frame parser with linecache
│ ├── variables.py # Local variable extractor
│ ├── history.py # VariableTracker (optional)
│ └── suggestions.py# Fallback suggestion generator
└── pyproject.toml
License
MIT
Metadata
Release files for askerror 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| askerror-0.1.0.tar.gz | 22.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| askerror-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.2 kB
Release files / askerror-0.1.0.tar.gz
| Download URL | askerror-0.1.0.tar.gz |
|---|---|
| Size | 22.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
99f74884ff5c577469930db6878201315f1463e7d5d3e0f130a03399af421e9c
|
|
BLAKE2b-256 checksum How to use checksums |
845a67dc3d3d4248c59140bb6fb7f2d9d3a2bc7824930aee84342069094fcd04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / askerror-0.1.0-py3-none-any.whl
| Download URL | askerror-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85906a71a13807c49b8d6f2fd441b065cd2866d84265425b8ea7beb892ba40eb
|
|
BLAKE2b-256 checksum How to use checksums |
306ed419d5fc5cde38b4a25fa286b6426ab58d3387b89406fec68dda6359f432
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|