# What Happens When a Module Throws an Exception During Execution in Holehe

> Discover what happens when a module throws an exception in Holehe. Learn how Holehe handles errors, records failures, and ensures scan continuity without crashing.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: internals
- Published: 2026-08-25

---

**When a module throws an exception during execution in Holehe, the `launch_module` coroutine in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) catches the error, appends a failure record with `"error": True` to the output list, and allows the remaining modules to continue running without crashing the entire scan.**

Holehe is a popular open-source email OSINT tool that checks for account existence across hundreds of online services. When a module throws an exception during execution in Holehe—whether due to network timeouts, unexpected HTML structures, or API changes—the tool implements a fail-soft strategy that prevents total execution failure while maintaining a consistent data schema for reporting.

## Exception Handling in the Core Execution Loop

The orchestration logic resides in **[`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)**, specifically within the `launch_module` coroutine. This function wraps each module call inside a broad `try … except Exception` block to ensure robust error isolation between individual service checks.

### The launch_module Coroutine

Between lines 66–78 of [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the execution flow protects against unhandled exceptions:

```python
async def launch_module(module, email, client, out):
    # ... setup code ...

    try:
        await module(email, client, out)
    except Exception:
        name = str(module).split('<function ')[1].split(' ')[0]
        out.append({
            "name": name,
            "domain": data[name],
            "rateLimit": False,
            "error": True,
            "exists": False,
            "emailrecovery": None,
            "phoneNumber": None,
            "others": None,
        })

```

If the awaited `module` call raises any exception, the code extracts the module name from its string representation, constructs a standardized error dictionary using the `data` mapping for domain resolution, and appends it to the shared `out` list.

## Error Result Structure

When a module fails, Holehe records a placeholder result with specific boolean flags that downstream functions interpret. The appended dictionary contains:

- **`"error": True`** — Indicates the module raised an exception during execution.
- **`"rateLimit": False`** — No rate-limit information is available when the module crashes.
- **`"exists": False`** — No positive account-existence evidence can be reported.
- **`"emailrecovery"`, `"phoneNumber"`, `"others"`** — Set to `None` because the exception prevented data extraction.

This structure ensures that the final output maintains consistent schema even for failed checks, allowing aggregation and sorting logic to proceed without null pointer errors.

## Visual Indicators in Terminal Output

The error status propagates to the user interface through the `print_result` function, also located in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py). Lines 26–31 check the `results["error"]` flag and render a red **`[!]`** marker next to the service name.

This visual feedback immediately alerts analysts that a particular module failed—distinguishing execution errors from negative account existence results—without interrupting the scan progress of remaining modules.

## Practical Example: Simulating a Module Failure

You can observe this behavior by programmatically triggering the exception handler. Below is a minimal reproduction that demonstrates how Holehe processes a faulty module:

```python
import asyncio
import httpx
from holehe.core import launch_module

async def faulty_module(email, client, out):
    # Simulate a runtime error (e.g., network timeout or parsing failure)

    raise RuntimeError("simulated module failure")

async def demo():
    results = []
    async with httpx.AsyncClient() as client:
        await launch_module(faulty_module, "test@example.com", client, results)
    
    print(results)
    # Output contains:

    # [{

    #   "name": "faulty_module",

    #   "domain": "unknown",

    #   "rateLimit": False,

    #   "error": True,

    #   "exists": False,

    #   "emailrecovery": None,

    #   "phoneNumber": None,

    #   "others": None

    # }]

asyncio.run(demo())

```

Running this snippet produces a standardized error entry for `faulty_module` while the event loop remains intact, proving that Holehe's architecture successfully isolates module failures from the overall execution context.

## Summary

- **Isolation**: The `launch_module` coroutine in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) wraps each module in a `try … except Exception` block to prevent cascading failures.
- **Logging**: Failed modules produce a consistent JSON structure with `"error": True`, `"exists": False`, and `null` data fields.
- **Continuity**: The shared `out` list receives the error record, allowing remaining modules to execute normally.
- **Visibility**: The `print_result` function renders red `[!]` indicators in terminal output to flag specific module failures.

## Frequently Asked Questions

### Does Holehe crash if a single module fails?

No. Holehe implements fail-soft behavior where the `launch_module` function catches all exceptions thrown by individual modules. The tool logs the failure and continues executing the remaining service checks without terminating the process or corrupting the results aggregation.

### How does Holehe indicate a module error in the terminal output?

According to the source code in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the `print_result` function checks for `results["error"]` and displays a red `[!]` marker next to the service name. This provides immediate visual distinction between execution failures and negative existence results.

### Can I see the original exception traceback when a module fails?

The current implementation in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) catches exceptions broadly without re-raising or logging the traceback to the standard output list. The error is silently captured and converted to a boolean flag, meaning the specific exception details are not preserved in the final results dictionary by default.

### Where is the exception handling logic implemented?

The primary exception handling logic resides in **[`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)** within the `launch_module` coroutine (approximately lines 66–78). This centralizes error management for all modules located in `holehe/modules/`, ensuring consistent behavior across the entire service catalog.