How the `launch_module` Wrapper Handles Exceptions from Website Modules in holehe

The launch_module wrapper in holehe catches all exceptions from website modules, logs them as structured error entries, and allows the main scanning loop to continue without interruption.

The holehe repository by megadose is an open-source email reconnaissance tool that checks whether an email address is registered on hundreds of websites. Since it runs dozens of concurrent website checks, robust error handling is essential. The launch_module function in holehe/core.py serves as the protective barrier between individual module failures and the overall scan integrity.

How launch_module Is Invoked

Modules are scheduled concurrently using Trio's nursery pattern. In holehe/core.py (lines 20–21), each website module is started as a background task:

async with trio.open_nursery() as nursery:
    for website in websites:
        nursery.start_soon(launch_module, website, email, client, out)

This schedules every module through the launch_module wrapper rather than calling modules directly.

Exception Handling Implementation

The launch_module function is defined in holehe/core.py (lines 66–78). It wraps module execution in a broad try/except block that captures any failure:

async def launch_module(module, email, client, out):
    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
        })

What Happens When a Module Fails

  1. Execution attempt – The wrapper awaits the module coroutine (module(email, client, out))
  2. Exception capture – Any Exception subclass triggers the except block
  3. Module identification – The function name is parsed from str(module) using string splitting on '<function '
  4. Structured logging – A uniform result dictionary is appended to the shared out list with:
    • name: extracted module identifier (e.g., "github")
    • domain: looked up from the static data mapping (e.g., "github.com")
    • rateLimit: False (no rate-limit information available)
    • error: True (signals this result represents a failure)
    • exists: False (no positive detection possible)
    • All data fields set to None

This guarantees every module produces exactly one result entry, maintaining consistent output structure regardless of success or failure.

Result Aggregation and Display

After all launch_module coroutines complete, results are sorted and rendered. The error: True flag triggers visual indicators in terminal output—failures appear with a red [!] tag, distinguishing them from successful negative results ([-]) or positive detections ([+]) without disrupting the scan flow.

Design Benefits

Aspect Implementation
Isolation One module's failure cannot crash others
Completeness Every module contributes to final output
Observability Errors are explicitly flagged, not silently dropped
Structured data Consistent schema for success and failure cases

Summary

  • launch_module in holehe/core.py is the defensive wrapper protecting holehe's concurrent scan loop
  • It catches all exceptions from website modules via except Exception:
  • Failed modules produce structured error entries with error: True, exists: False, and rateLimit: False
  • The module name extraction uses string parsing on str(module) to identify the failed checker
  • Main scan execution continues unaffected by individual module crashes

Frequently Asked Questions

What happens if a website module raises an exception in holehe?

The launch_module wrapper catches it, constructs a failure result entry with error: True, and appends it to the output list. The main scanning loop continues with other modules.

How does holehe identify which module failed?

It extracts the function name from str(module) by splitting on '<function ' and taking the first token. This parsed name is used to look up the corresponding domain in the static data mapping.

Why does launch_module use except Exception instead of specific exceptions?

A broad handler ensures no module can crash the scan, whether it raises network errors, parsing failures, or unexpected bugs. The trade-off is uniform error reporting without granular failure classification.

Where is the launch_module function defined in the holehe codebase?

It is implemented in holehe/core.py at lines 66–78, invoked from the main async orchestration code around lines 20–21.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →