Files
noteflow/.claude/hookify.block-broad-exception-handler.local.md
Travis Vasceannie 1ce24cdf7b feat: reorganize Claude hooks and add RAG documentation structure with error handling policies
- Moved all hookify configuration files from `.claude/` to `.claude/hooks/` subdirectory for better organization
- Added four new blocking hooks to prevent common error handling anti-patterns:
  - `block-broad-exception-handler`: Prevents catching generic `Exception` with only logging
  - `block-datetime-now-fallback`: Blocks returning `datetime.now()` as fallback on parse failures to prevent data corruption
  - `block-default
2026-01-15 15:58:06 +00:00

1.8 KiB

name, enabled, event, conditions, action
name enabled event conditions action
block-broad-exception-handler true file
field operator pattern
new_text regex_match except\s+Exception\s*(?:as\s+\w+)?:\s*\n\s+(?:logger.|logging.)
block

BLOCKED: Broad except Exception: handler detected

Catching generic Exception and only logging creates silent failures that are nearly impossible to debug.

Why this is dangerous:

  • Catches ALL exceptions including programming errors (TypeError, AttributeError)
  • Hides bugs that should crash loudly and be fixed immediately
  • Makes the system appear to work while silently failing
  • Log messages get lost in noise; exceptions should bubble up

Acceptable uses (require explicit justification):

  1. Top-level handlers in background tasks that MUST NOT crash
  2. Fire-and-forget operations where failure is truly acceptable
  3. User-provided callbacks that could raise anything

If you believe this is acceptable, add a comment:

# INTENTIONAL BROAD HANDLER: <reason>
# - <specific justification>
# - <what happens on failure>

What to do instead:

  1. Catch specific exception types you can handle
  2. Let unexpected exceptions propagate
  3. Use domain-specific exceptions from src/noteflow/domain/errors.py

Resolution pattern:

# BAD: Catches everything silently
except Exception:
    logger.exception("Something failed")

# GOOD: Specific exceptions
except (ValueError, KeyError) as e:
    logger.warning("Config parse error: %s", e)
    raise ConfigError(str(e)) from e

# GOOD: Let others propagate
except ValidationError as e:
    logger.error("Validation failed: %s", e)
    raise  # Re-raise or wrap in domain error

If truly fire-and-forget, surface metrics:

except Exception:
    logger.exception("Background task failed")
    metrics.increment("background_task_failures")  # Observable!