Skip to content

Fix: Narrow except Exception to except SQLAlchemyError in health_check()#941

Open
Bornunique911 wants to merge 2 commits into
OWASP:mainfrom
Bornunique911:fix/issue-940-health-check-exception
Open

Fix: Narrow except Exception to except SQLAlchemyError in health_check()#941
Bornunique911 wants to merge 2 commits into
OWASP:mainfrom
Bornunique911:fix/issue-940-health-check-exception

Conversation

@Bornunique911

Copy link
Copy Markdown
Contributor

Summary

Fixes overly broad exception handling in Node_collection.health_check() by replacing except Exception with except SQLAlchemyError.

Closes #940

Problem

The health_check() method in application/database/db.py currently uses a generic except Exception as a fallback after catching OperationalError:

except OperationalError:
    return {"ok": False, "db_reachable": False, "reason": "database unreachable"}
except Exception:  # pragma: no cover - defensive, never fail open
    return {"ok": False, "db_reachable": False, "reason": "database health query failed"}

This broad catch silently swallows programming bugs such as AttributeError, TypeError, or NameError within the health check logic itself. Instead of propagating the error (which would reveal the bug), it returns a structured {"ok": False} response, making such issues very hard to detect.

Solution

  • Add SQLAlchemyError to the import from sqlalchemy.exc

  • Replace except Exception: with except SQLAlchemyError:.

Since OperationalError is a subclass of SQLAlchemyError and is caught first, the new clause only handles remaining SQLAlchemy-level errors.

Changes

File: application/database/db.py

Change 1 – Import (line ~26):

- from sqlalchemy.exc import OperationalError, IntegrityError
+ from sqlalchemy.exc import OperationalError, IntegrityError, SQLAlchemyError

Change 2 – Exception handler (lines ~2292–2296):

- except Exception:  # pragma: no cover - defensive, never fail open
+ except SQLAlchemyError:
      return {
          "ok": False,
          "db_reachable": False,
          "reason": "database health query failed",
      }

Behavioral Change

⚠️ Important: Non-SQLAlchemy exceptions (e.g., programming bugs) will now propagate naturally rather than being swallowed. This is intentional — bugs should surface during development/testing, not be hidden behind a structured health-check response.

In production, this means:

Before: Any unexpected error → {"ok": False, ...} (bug hidden)

After: SQLAlchemy errors → {"ok": False, ...}; programming bugs → HTTP 500 with stack trace (bug visible)

Related Issue

Closes #940

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: fb06e815-c162-421b-9f43-b08bbd7f6582

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

In application/database/db.py, SQLAlchemyError is added to the existing sqlalchemy.exc import, and the fallback except Exception block in health_check() is replaced with except SQLAlchemyError. The returned failure payload is unchanged.

Changes

Health Check Exception Narrowing

Layer / File(s) Summary
Import and handler narrowing in health_check()
application/database/db.py
SQLAlchemyError is added to the sqlalchemy.exc import at line 26, and the broad except Exception fallback in health_check() is replaced with except SQLAlchemyError, leaving the "database health query failed" return payload intact.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: narrowing the exception handler from Exception to SQLAlchemyError in health_check().
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the problem, solution, and behavioral implications of the exception handling changes.
Linked Issues check ✅ Passed The PR fully implements all requirements from issue #940: imports SQLAlchemyError, replaces except Exception with except SQLAlchemyError, achieving the objective of catching only database-layer exceptions.
Out of Scope Changes check ✅ Passed All changes are narrowly scoped to the stated objectives: one import addition and one exception handler modification in application/database/db.py.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Bornunique911

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix overly broad exception handling in Node_collection.health_check to catch SQLAlchemyError only

1 participant