Metadata-Version: 2.4
Name: askerror
Version: 0.1.0
Summary: Beautiful, contextual Python error explanations — offline, automatic, actionable
Author: Muneeb Arshad
License: MIT
Project-URL: Homepage, https://github.com/muneeb/askerror
Project-URL: Source, https://github.com/muneeb/askerror
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Debuggers
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: rich>=13.0.0
Requires-Dist: easydotdict>=1.0.0

# 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

```bash
pip install askerror
```

Requires Python 3.8+.

---

## Usage

### Method 1 — Import and Install

```python
import askerror
askerror.install()
```

Every uncaught exception from that point onward is formatted beautifully.

```python
# examply.py
import askerror
askerror.install()

items = None
items.append("hello")
```

Run it:

```bash
python examply.py
```

### Method 2 — Decorator

```python
from askerror import explain

@explain
def main():
    items = None
    items.append("hello")

main()
```

### Method 3 — CLI

Run any script with beautified errors:

```bash
askerror run app.py
```

```bash
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`.

```bash
askerror run server.py --port 8080
```

### `askerror doctor`

Checks your Python environment:

- Python version
- Virtual environment status
- `rich` and `easydotdict` installation
- Config file status

```bash
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

```bash
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 string
- `float("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:

```python
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:

```bash
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`.

```python
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
