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
- Execution attempt – The wrapper
awaits the module coroutine (module(email, client, out)) - Exception capture – Any
Exceptionsubclass triggers theexceptblock - Module identification – The function name is parsed from
str(module)using string splitting on'<function ' - Structured logging – A uniform result dictionary is appended to the shared
outlist with:name: extracted module identifier (e.g.,"github")domain: looked up from the staticdatamapping (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_moduleinholehe/core.pyis 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, andrateLimit: 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →