Metadata-Version: 2.4
Name: pyerror-intel
Version: 0.1.0
Summary: A Python error intelligence library for learners and production systems.
Home-page: https://github.com/Happy-Kumar-Sharma/error
Author: Happy Sharma
Author-email: happycse54@gmail.com
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: rich>=12.0.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# pyerror 🧠

[![PyPI Version](https://img.shields.io/pypi/v/pyerror-intel.svg)](https://pypi.org/project/pyerror-intel/)
[![Python Version](https://img.shields.io/pypi/pyversions/pyerror-intel.svg)](https://pypi.org/project/pyerror-intel/)
[![License](https://img.shields.io/github/license/Happy-Kumar-Sharma/error.svg)](https://github.com/Happy-Kumar-Sharma/error/blob/main/LICENSE)

> **Because common sense is not so common. Now it is — in Python!**
> A Python error intelligence library for learners, developers, and production systems.

Most traceback libraries just pretty-print logs. `pyerror` understands your errors, translates them into plain English, suggests exact fixes, captures local scope details, and recovers gracefully when needed. 

It works in **two modes**:
*   **Beginner Mode**: Formatted specifically for students. Hides intimidating internal library frames, translates jargon to plain English, and explains the concepts.
*   **Power Mode**: Built for developers and production apps. Captures snapshots of local variables at the moment of failure (while masking secrets), filters tracebacks, aggregates error analytics, and formats logs into structured JSON.

---

## 🚀 Key Features

*   **Human-Readable Tracebacks**: Translates complex traceback outputs into friendly, clear, plain-English explanations.
*   **Actionable Fix Suggestions**: Generates exact, context-aware suggestions for standard Python exceptions (KeyError, TypeError, AttributeError, ValueError, and more).
*   **Decorators for Resiliency**: Includes `@retry` with exponential backoff, `@capture_locals` to snapshot scope at failure, and `@fallback` for graceful degradation.
*   **Safety Net Contexts**: Clean exception suppressing with `with ignore(...)`.
*   **Dynamic Custom Exception Factory**: Create rich, professional custom exception classes in one line with built-in templates and suggestions.
*   **Error Diff Comparison**: Visualize and explain type/value differences using `pyerror.compare(expected, got)`.
*   **Error Analytics**: Automatically groups and counts repeated exceptions across project runs.
*   **Environment Adapting Display**: Renders beautifully colorized panels in the Terminal, interactive HTML accordion containers in **Jupyter Notebooks**, and clean JSON in **Production Logs**.

---

## 📦 Installation

Install the package via `pip`:

```bash
pip install pyerror-intel
```

*(Note: The package is imported as `pyerror` in your scripts)*

---

## 🎮 Quick Start

### For Beginners (Students)
Turn on `beginner_mode` at the top of your script. Any uncaught exceptions will be output as friendly explanations.

```python
import pyerror
pyerror.beginner_mode(True)

# Let's trigger a NameError:
print(unknown_variable)
```

**Output in Terminal:**
```text
=== [ERROR] NameError: name 'unknown_variable' is not defined ===

💡 Error Explanation:
You used a variable, function, or module name that has not been defined yet.
Python searched for the name 'unknown_variable' in your code but couldn't find any definition for it.

🔍 Traceback (Filtered):
  File "quickstart.py", line 5 in <module>
    print(unknown_variable)

🛠️ Suggestions:
  * Check for spelling mistakes or typos in the name 'unknown_variable'.
  * Ensure that you have defined the variable/function BEFORE trying to use it.
  * If 'unknown_variable' is from an external library, make sure you have imported it.
```

---

### For Developers (Power Mode)

Enable customized error formatting with `humanize()` and configure traceback styles:

```python
import pyerror

# Enable formatting and log tracking
pyerror.humanize(True)
pyerror.configure(traceback_mode="compact") # compact, full, beginner, or production
```

#### 1. Scope Variable Snapshot (`@capture_locals`)
Snapshot local variables immediately when a function fails. Secrets like tokens and passwords are automatically masked!

```python
@pyerror.capture_locals
def calculate_ratio(total, count, api_key="secret-token-123"):
    fraction = total / count
    return fraction

calculate_ratio(10, 0)
```

#### 2. Graceful Decorators (`@retry` & `@fallback`)
Add resiliency and default values to unstable functions:

```python
# Retry calling 3 times with exponential backoff and full jitter on ConnectionError
@pyerror.retry(tries=3, delay=1.0, backoff=2.0, jitter=True, exceptions=(ConnectionError,))
def fetch_user_data():
    # your api call logic
    pass

# Fallback gracefully instead of crashing
@pyerror.fallback(default=[])
def load_cached_items():
    raise FileNotFoundError("Cache file missing")
    
print(load_cached_items()) # Outputs: []
```

#### 3. Safety Net Context Managers (`ignore`)
Safely ignore specific errors when executing cleanup operations:

```python
import os

# Safely ignore if file doesn't exist
with pyerror.ignore(FileNotFoundError):
    os.remove("temporary_log.txt")
```

---

## 🛠️ Diagnostics & Utilities

### Exception Explanation (`pyerror.explain` & `pyerror.suggest`)
Explain caught exceptions on demand:

```python
try:
    my_dict = {"id": 1}
    val = my_dict["name"]
except KeyError as exc:
    # Get direct suggestions
    print(pyerror.suggest(exc))
    
    # Or get details & display them (Renders beautiful HTML in Jupyter Notebooks!)
    pyerror.explain(exc).show()
```

### Type and Value Comparison (`pyerror.compare`)
Compare types or values and output a readable description and suggested cast:

```python
# Type mismatch comparison
pyerror.compare(expected=int, got=str, value="42").show()
```

### Rich Custom Exception Factory (`pyerror.create`)
Create highly informative custom exceptions instantly:

```python
UserNotFound = pyerror.create(
    "UserNotFound",
    message="User profile with ID {user_id} was not found in database.",
    suggestions=[
        "Confirm the user ID exists in the admin dashboard.",
        "Check if the database connection is healthy.",
        "Verify caching headers."
    ]
)

raise UserNotFound(user_id=8923)
```

---

## 📊 Error Analytics & Grouping
`pyerror` automatically logs and groups exception counts across project executions into `.error_analytics.json`. You can print this breakdown at the end of an execution, or build reports:

```python
# Fetch error analytics report
report = pyerror.get_analytics()

# Display beautiful summary table
report.show()

# Or clear stats
pyerror.clear_analytics()
```

---

## 🔌 Webhooks & Integrations
Notify Slack, Sentry, or send emails automatically when failures occur.

```python
# Configure credentials
pyerror.configure_integrations(
    slack_webhook="https://hooks.slack.com/services/...",
    sentry_dsn="https://...",
    email_config={
        "host": "smtp.mailtrap.io",
        "port": 2525,
        "sender": "alerts@myproject.com",
        "recipient": "dev-ops@myproject.com",
        "username": "smtp-username",
        "password": "smtp-password"
    }
)

try:
    # Trigger an issue
    1 / 0
except ZeroDivisionError as exc:
    # Post rich details to Slack Webhook blocks
    pyerror.notify_slack(exc)
    
    # Forward exception to Sentry
    pyerror.notify_sentry(exc)
    
    # Send HTML diagnostic email
    pyerror.send_email(exc)
```

---

## 🔒 Advanced Privacy Filter
In addition to local variable masking, `pyerror` scrubs passwords, Basic Auth tokens, API keys, and Credit Card details directly from exception messages, tracebacks, and source lines.

You can register custom secrets to match:
```python
# Any local variable or text matching "auth_token" will be masked
pyerror.add_privacy_rule("auth_token")
```

---

## 🔗 Self-Contained Sharing Links
Compresses exception data using `zlib` and `base64` to generate sharing links. Excellent for sharing diagnostic reports with other developers:

```python
try:
    my_function()
except Exception as exc:
    link = pyerror.generate_share_link(exc)
    # Outputs: https://happy-kumar-sharma.github.io/error/viewer.html?data=eJxtz0kO...
```

---

## 📝 Markdown Report Generation
Create standard Markdown diagnostics logs for archiving or attaching to GitHub Issues/Triage tickets:

```python
try:
    load_database()
except ConnectionError as exc:
    # Save a detailed report to a markdown file
    pyerror.generate_markdown_report(exc, file_path="logs/database_failure.md")
```

---

## 🧪 Unit Test Helpers
Assert that your custom exceptions match human-readability standards and do not leak plain-text credentials:

```python
import unittest
import pyerror

class TestMyCode(unittest.TestCase):
    def test_custom_exception(self):
        try:
            # Code that raises UserNotFound
            raise UserNotFound(user_id=10)
        except Exception as exc:
            # 1. Assert exception has clear explanation, why description, and >= 2 suggestions
            pyerror.assert_readable(exc, min_suggestions=2)
            
            # 2. Assert local scopes do not leak any passwords, keys, or secret keys
            pyerror.assert_not_exposed(exc)
```

---

## ⚙️ Configuration Options

Customize behavior with `pyerror.configure(...)`:

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `traceback_mode` | `str` | `"full"` | Traceback level: `"beginner"`, `"compact"`, `"full"`, or `"production"` (outputs JSON). |
| `mask_secrets` | `bool` | `True` | Automatically mask password/token variables in local snapshots. |
| `secret_keys` | `list` | `[...]` | Custom variable names to mask (case-insensitive substring match). |

---

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
