Skip to main content
ai-slop/silent-recoverymanual fix

Silent recovery.

A catch or except block that logs a message without the caught error and carries on. The failure is noticed and its cause thrown away.

Flagged shape and clean shape.

Each example shows the exact code shape the rule is looking for, then the smallest version that keeps the intent without hiding risk or adding noise.

silent-recovery.py
✗ Flagged
def refresh_exchange_rates():
    try:
        rates = provider.fetch_rates()
        cache.set("rates", rates)
    except ProviderError:
        logger.warning("could not refresh exchange rates")
Why this trips

Deterministic block parse on JS/TS and Python: flags handlers whose body is only log or print calls, with no throw, raise, return, or assignment, and which never reference the caught error.

silent-recovery.py
✓ Clean
def refresh_exchange_rates():
    try:
        rates = provider.fetch_rates()
        cache.set("rates", rates)
    except ProviderError:
        logger.exception("could not refresh exchange rates")
        raise
What changed

Include the caught error in the log, or re-raise or recover explicitly, so the failure stays diagnosable.

Agents add a log line so the handler looks responsible but leave out the exception itself, so the log says something failed and never what.

How this rule is justified.

Rule id

ai-slop/silent-recovery

Enforcing engine

ai-slop

Detector strategy

Deterministic block parse on JS/TS and Python: flags handlers whose body is only log or print calls, with no throw, raise, return, or assignment, and which never reference the caught error.

Legitimate code that is NOT flagged

Handlers that include the error in the log, Python handlers using `logger.exception(...)` or `exc_info=True`, handlers that re-raise, return, or otherwise recover, `pass` bodies, and non-production paths are not flagged.

Evidence

Introduced in aislop v0.9.5.