Skip to main content

A Python error intelligence library for learners and production systems.

Project description

pyerror 🧠

PyPI Version Python Version License

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

pyerror is a complete diagnostics ecosystem that translates tracebacks, suggests fixes, captures local scope details safely, and recovers gracefully when needed. It works in the Terminal, Jupyter Notebooks, and Production environments.


📦 Installation

Install the package via pip:

pip install pyerror-intel

(Note: Always import the library as pyerror in your scripts)


🎮 Complete Functionality Reference

Below is a detailed guide on all 28 public APIs and configurations provided by pyerror, categorized by feature area.


1. Core Interface

pyerror.beginner_mode(enable: bool)

Enables or disables beginner mode. Sets the traceback output to a minimalist visual panel (hiding library internals) and translates exceptions into friendly explanation blocks. Ideal for classrooms or coding bootcamps.

import pyerror
pyerror.beginner_mode(True) # Turns on beginner mode

# Triggering an error:
print(x) # Raises NameError and prints simple explanation panel

pyerror.humanize(enable: bool)

Overrides the default sys.excepthook with the pyerror formatting console handler. Uncaught exceptions will automatically print the detailed explanation panels.

import pyerror
pyerror.humanize(True) # Activates humanized excepthooks

pyerror.configure(...)

Configures global library parameters:

  • traceback_mode: "beginner", "compact", "full", or "production" (JSON output).
  • mask_secrets: True / False to enable local variable masking.
  • secret_keys: list of keys to mask.
  • hide_packages: list of package names (e.g. ["requests"]) to filter out of traceback stacks.
  • git_blame: True / False to enable git blame author attribution on user traceback frames.
pyerror.configure(
    traceback_mode="compact",
    mask_secrets=True,
    secret_keys=["db_password", "auth_token"],
    hide_packages=["numpy", "pandas"]
)

pyerror.inspect_last_error()

A post-mortem utility for interactive REPL or Python console sessions. Inspects sys.last_value from the most recent crash and prints its formatted report.

>>> import pyerror
>>> print(x)
NameError: name 'x' is not defined
>>> pyerror.inspect_last_error() # Prints humanized report panel for NameError

pyerror.debug_wizard()

Launches an interactive, text-based CLI debug wizard in your REPL/console session to troubleshoot the last active or thrown exception. It prompts you with options to translate the error, inspect captured local variables, generate sharing links, write markdown reports, or launch pdb for post-mortem debugging.

>>> import pyerror
>>> raise ValueError("Invalid config")
>>> pyerror.debug_wizard()
# Launches interactive triage menu console

2. Diagnostics & On-Demand Analysis

pyerror.explain(exc: BaseException)

Returns a DiagnosticsResult wrapper containing translation, reason, suggestions, and source lines. Support rendering as a string or rich print.

try:
    1 / 0
except ZeroDivisionError as exc:
    # Prints premium diagnostic panels (Terminal colorized)
    pyerror.explain(exc).show()

pyerror.diagnose(exc: BaseException)

Similar to explain, retrieves detailed diagnostic data and returns a DiagnosticsResult object. In Jupyter Notebooks, it renders interactive HTML accordion widgets automatically.

# In Jupyter Notebook cell:
try:
    my_list = [1, 2]
    val = my_list[5]
except IndexError as exc:
    pyerror.diagnose(exc) # Renders responsive HTML widget in Jupyter output

pyerror.suggest(exc: BaseException)

Returns a Python list of strings containing actionable steps to resolve the caught exception.

try:
    import invalid_library
except ModuleNotFoundError as exc:
    suggestions = pyerror.suggest(exc)
    print(suggestions)
    # Output: ["Install the module using pip...", "Verify you are running...", ...]

pyerror.compare(expected: Any, got: Any, value: Any = None)

Compares types or values and returns a ComparisonResult detailing the difference and offering code suggestions for casting or validation.

# Value mismatch check
pyerror.compare(expected=int, got=str, value="100").show()

3. Resiliency Decorators

@pyerror.capture_locals

Decorates a function so that if it crashes, a snapshot of all local variables is captured inside the exception object (as exc.__captured_locals__). Secrets and keys are automatically masked.

@pyerror.capture_locals
def process_data(user_id, token="secret_token"):
    result = user_id + "100" # Raises TypeError
    return result

try:
    process_data(42)
except TypeError as exc:
    print(exc.__captured_locals__)
    # Output: {'process_data': {'user_id': '42', 'token': '********'}}

@pyerror.retry(...)

Retries calling the decorated function on failure.

  • tries: Number of attempts.
  • delay: Wait time in seconds between retries.
  • backoff: Multiplier to increase delay exponentially.
  • jitter: True / False to randomize delay intervals (prevents thundering herds).
  • exceptions: Tuple of exception types to trigger retries.
@pyerror.retry(tries=3, delay=1.0, backoff=2.0, jitter=True, exceptions=(ConnectionError,))
def connect_to_server():
    # Attempt network connection
    raise ConnectionError("Timeout")

@pyerror.fallback(default, exceptions=Exception)

Catches specified exceptions inside the decorated function and returns the provided default fallback value instead of crashing.

@pyerror.fallback(default={}, exceptions=(FileNotFoundError, ValueError))
def load_config():
    raise FileNotFoundError("Config missing")

print(load_config()) # Returns: {}

@pyerror.circuit_breaker(failure_threshold=5, recovery_timeout=60.0, exceptions=Exception)

A decorator implementing the Circuit Breaker pattern. It tracks consecutive failures raised by the decorated function.

  • failure_threshold: Number of consecutive failures before the circuit opens.
  • recovery_timeout: Cooldown period in seconds before transitioning to half-open.
  • exceptions: Tuple of exception types that trigger failure tracking. Once opened, subsequent calls instantly raise pyerror.CircuitOpenError without running the function. After the recovery timeout, it transitions to half-open, running a canary call to check health.
@pyerror.circuit_breaker(failure_threshold=3, recovery_timeout=30.0, exceptions=(ValueError,))
def call_unstable_api():
    raise ValueError("API is down")

# After 3 failed calls, the circuit opens:
try:
    call_unstable_api()
except pyerror.CircuitOpenError as exc:
    print("Circuit is currently open, call was blocked.")

#### `@pyerror.self_healing(handler, exceptions=Exception)`
Decorates a function to catch specified exceptions, invoke a custom recovery handler, and retry the function call exactly once.
```python
def recovery_handler(exc):
    print("OAuth token expired, refreshing...")
    refresh_oauth_token()

@pyerror.self_healing(handler=recovery_handler, exceptions=(ExpiredTokenError,))
def call_protected_api():
    # triggers ExpiredTokenError on first try
    pass

---

### 4. Context Managers

#### `pyerror.ignore(*exceptions)`
Safely silences specified exceptions during code execution.
```python
import os
# Ignores FileNotFoundError if file is already deleted
with pyerror.ignore(FileNotFoundError):
    os.remove("nonexistent.txt")

pyerror.capture_scope()

A block-level context manager that captures all local variables initialized or modified inside a code block if an exception is raised. Variables matching secret names (like passwords, keys) are automatically masked. The captured dictionary is stored in scope.locals and attached to exc.__captured_locals__.

try:
    with pyerror.capture_scope() as scope:
        db_user = "admin"
        db_password = "my-secret-password"
        result = 10 / 0
except ZeroDivisionError as exc:
    print(scope.locals)
    # Output: {'db_user': "'admin'", 'db_password': '********', 'result': ...}

5. Custom Exceptions

pyerror.create(name: str, message: str, suggestions: list)

Dynamically creates a custom Exception class. Supports string format parameters (message.format(**kwargs)) and embeds recommendations directly into the exception object.

DatabaseFailure = pyerror.create(
    "DatabaseFailure",
    message="Connection lost to host: {host}",
    suggestions=["Verify network interface", "Ping database hostname"]
)

# Raise custom exception
raise DatabaseFailure(host="db.local")

6. Logging & Exporting Reports

pyerror.integrate_logging(max_tail_lines: int = 20)

Attaches a memory-bounded log aggregator handler (pyerrorLogHandler) to the Python root logger. It holds the last $N$ logs and embeds them automatically inside markdown reports, JSON tracebacks, and Jupyter HTML outputs when an exception occurs.

import logging
import pyerror

pyerror.integrate_logging(max_tail_lines=15)
logging.getLogger().info("User started computation")
# Any crash after this point will include this log in JSON/HTML/Markdown outputs!

pyerror.to_json(exc: BaseException) -> str

Serializes the exception type, message, translation, reasons, suggestions, and traceback frames (with scrubbed variables) into a structured JSON string.

try:
    1 / 0
except ZeroDivisionError as exc:
    json_log = pyerror.to_json(exc)
    print(json_log)

pyerror.generate_markdown_report(exc: BaseException, file_path: str = None) -> str

Generates a detailed markdown diagnostic report. If file_path is specified, writes the report directly to that file.

try:
    db_query()
except Exception as exc:
    pyerror.generate_markdown_report(exc, file_path="triage_report.md")

pyerror.generate_share_link(exc: BaseException) -> str

Compresses exception data and creates a self-contained, base64-encoded URL sharing link pointing to the static exception viewer client.

try:
    raise ValueError("Invalid credentials configuration")
except Exception as exc:
    link = pyerror.generate_share_link(exc)
    print("Send this link to developer chat:", link)
    # Output: https://happy-kumar-sharma.github.io/error/viewer.html?data=eJyN...

7. System & Analytics Tracking

pyerror.get_system_info() -> dict

Returns system specs (OS version, architecture, CPU count, memory usage) and environment variables scrubbed of passwords/keys.

stats = pyerror.get_system_info()
print(stats["os_platform"]) # E.g., Windows
print(stats["memory_usage_percent"]) # E.g., 45.2

pyerror.get_analytics()

Retrieves the logged analytics data. Identifies recurring errors across runs, showing frequency metrics and timestamps.

report = pyerror.get_analytics()
report.show() # Prints recurring exception summary table

pyerror.clear_analytics()

Clears all recorded exception analytics records.

pyerror.clear_analytics()

8. Web Framework Integrations

pyerror.register_flask_error_handler(app)

Registers a global handler on a Flask application instance to catch all unhandled route exceptions and return structured JSON diagnostic responses.

from flask import Flask
import pyerror

app = Flask(__name__)
pyerror.register_flask_error_handler(app)

@app.route("/")
def index():
    return 1 / 0 # Automatically caught and formatted as JSON with 500 code

pyerror.FastAPIErrorMiddleware

ASGI middleware class for FastAPI / Starlette applications to catch routing exceptions and return humanized JSON responses.

from fastapi import FastAPI
import pyerror

app = FastAPI()
app.add_middleware(pyerror.FastAPIErrorMiddleware)

9. Slack, Sentry, & Email Alerts

pyerror.configure_integrations(slack_webhook=None, sentry_dsn=None, email_config=None, rate_limit_seconds=None)

Sets up notification destinations for error routing.

  • rate_limit_seconds: window in seconds to suppress and debounce duplicate alerts. Aggregated counts are sent automatically when the rate limit window closes.
pyerror.configure_integrations(
    slack_webhook="https://hooks.slack.com/services/...",
    sentry_dsn="https://...",
    email_config={
        "host": "smtp.example.com",
        "port": 587,
        "sender": "alerts@myproject.com",
        "recipient": "admin@myproject.com",
        "username": "smtp-user",
        "password": "smtp-password"
    },
    rate_limit_seconds=300 # Debounce alerts for 5 minutes
)

pyerror.notify_slack(exc: BaseException)

Posts exception diagnostics to the configured Slack Webhook using Block Kit layout.

try:
    1 / 0
except Exception as exc:
    pyerror.notify_slack(exc)

pyerror.notify_sentry(exc: BaseException)

Captures and sends the exception details to the configured Sentry DSN endpoint.

try:
    1 / 0
except Exception as exc:
    pyerror.notify_sentry(exc)

pyerror.send_email(exc: BaseException)

Compiles and sends a structured HTML report email containing the exception's diagnostics and traceback.

try:
    1 / 0
except Exception as exc:
    pyerror.send_email(exc)

10. Privacy & Security

pyerror.add_privacy_rule(pattern: str)

Registers a case-insensitive variable/text pattern. If any variable name in local snapshots or text in tracebacks matches the rule, it is replaced with ********.

pyerror.add_privacy_rule("session_token")

pyerror.add_scrub_pattern(pattern: str, replacement: str = "********")

Adds a custom regular expression and replacement string to scrub sensitive data (like SSNs, credit cards, or internal user names) from tracebacks.

pyerror.add_scrub_pattern(r"\b\d{3}-\d{2}-\d{4}\b", "[SSN-MASKED]")

pyerror.add_scrub_callback(callback: Callable[[str], str])

Registers a custom sanitization function that takes a text block and returns the cleaned text block.

pyerror.add_scrub_callback(lambda text: text.replace("DUMMY_SECRET", "CLEAN"))

11. Unit Test Helpers

pyerror.assert_readable(exc: BaseException, min_suggestions: int = 1)

Asserts that an exception has a registered translation, why reason, and a minimum number of suggestions. Excellent for validating custom exceptions.

import unittest
import pyerror

class TestCustomErrors(unittest.TestCase):
    def test_readability(self):
        exc = MyException()
        pyerror.assert_readable(exc, min_suggestions=1)

pyerror.assert_not_exposed(exc: BaseException)

Asserts that the exception's local snapshots (if captured) do not contain unmasked secret key values (like passwords, keys, tokens).

import unittest
import pyerror

class TestSecurity(unittest.TestCase):
    def test_secrets_masked(self):
        try:
            # function with @capture_locals
            sensitive_function() 
        except Exception as exc:
            pyerror.assert_not_exposed(exc)

⚙️ Configuration Table

Configure settings anytime using pyerror.configure(...).

Parameter Type Default Description
traceback_mode str "full" Traceback level: "beginner", "compact", "full", or "production".
mask_secrets bool True Automatically mask password/token variables in local snapshots.
secret_keys list [...] Custom variable names to mask (case-insensitive substring match).
hide_packages list [] List of package names to filter out of traceback stacks.
git_blame bool False Run git blame on user traceback frames to identify author, commit, and date details.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyerror_intel-0.1.3.tar.gz (54.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyerror_intel-0.1.3-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

Details for the file pyerror_intel-0.1.3.tar.gz.

File metadata

  • Download URL: pyerror_intel-0.1.3.tar.gz
  • Upload date:
  • Size: 54.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.3

File hashes

Hashes for pyerror_intel-0.1.3.tar.gz
Algorithm Hash digest
SHA256 259d9fa0432b68ccf11070d81408fe5ea7ab69c298747255a449eea3923e49ff
MD5 d21d246693b676ee082df14625472a4e
BLAKE2b-256 fcc50f584c6ad65b38eed4c02758f9d85e59af801da258e1a35a3a655ed760bb

See more details on using hashes here.

File details

Details for the file pyerror_intel-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: pyerror_intel-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 47.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.3

File hashes

Hashes for pyerror_intel-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 652221e4aad81d26f7902df91fa8dd455bf23c02adff9e3d0e6ebed0d85a94e0
MD5 404662d8a0925922e81261e1da6ca851
BLAKE2b-256 1f39e6ed9e979642155fd573bac1b57e151ce897fc25ea6251d037120283f9d6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page