Skip to content

fix(tools): catch uncaught exceptions in submit_cves (ValueError) and get_github_advisory (ValueError) - #95

Merged
manus-use merged 1 commit into
mainfrom
fix/uncaught-exceptions
Jul 5, 2026
Merged

fix(tools): catch uncaught exceptions in submit_cves (ValueError) and get_github_advisory (ValueError)#95
manus-use merged 1 commit into
mainfrom
fix/uncaught-exceptions

Conversation

@manus-use

Copy link
Copy Markdown
Owner

Summary

Fixes two real exception-safety bugs found by the previous test suites and flagged in the evolution log. Neither was cosmetic — both caused callers to receive an unexpected exception instead of the documented {"status": "error"} / error-dict response.


Bug 1 — submit_cves: ValueError for missing webhook URL escaped try/except

File: src/manus_agent/tools/submit_cves.py

Root cause: The raise ValueError(...) guard for a missing CVE_SUBMIT_URL was placed outside the try/except block. Any caller that hadn't configured the webhook received a raw ValueError instead of the expected {"status": "error", ...} dict.

Fix: Moved URL resolution (Config.from_file() lookup + os.environ.get fallback + raise) inside the try block so the existing broad except Exception handler catches it and returns a proper error response — consistent with all other error paths in the function.

Before:

config = Config.from_file()
url = getattr(...)
if not url:
    raise ValueError("... not set ...")   # ← OUTSIDE try block — uncaught!
headers = ...
try:
    for cve in cve_list:
        ...
except Exception as err:
    return {"status": "error", ...}       # ← never reached for ValueError

After:

try:
    config = Config.from_file()
    url = getattr(...)
    if not url:
        raise ValueError("... not set ...")   # ← now INSIDE try block
    headers = ...
    for cve in cve_list:
        ...
except Exception as err:
    return {"status": "error", ...}           # ← catches ValueError too

Bug 2 — get_github_advisory: ValueError missing from except clause

File: src/manus_agent/tools/get_github_advisory.py

Root cause: The final except (KeyError, IndexError) clause did not include ValueError. response.json() raises ValueError (and its subclass json.JSONDecodeError) when the response body is malformed — a real scenario for transient API errors returning HTML error pages. These exceptions escaped silently to the caller.

Fix: One-line change — expand to except (KeyError, IndexError, ValueError).

Before:

except (KeyError, IndexError):
    result = {"error": "Received an unexpected response format..."}

After:

except (KeyError, IndexError, ValueError):
    result = {"error": "Received an unexpected response format..."}

Tests — tests/test_bug_fixes.py (18 new, 0 failures)

Bug 1 coverage (10 tests):

  • Missing URL → status == "error", never raises, toolUseId preserved, error text mentions config key
  • Happy path: URL via CVE_SUBMIT_URL env var → requests.post called, returns success
  • Happy path: URL via config.webhooks.cve_submit_url → returns success
  • Env var used when config.webhooks is None
  • HTTPError from requests.post still caught and returned
  • ConnectionError still caught and returned

Bug 2 coverage (8 tests):

  • ValueError from response.json() → returns {"error": ...} dict, never raises
  • json.JSONDecodeError (subclass of ValueError) → also caught
  • IndexError still caught (regression guard)
  • HTTP 404 still returns {"message": "No advisory found..."} (regression guard)
  • Happy path with valid advisory list unaffected
  • Input validation short-circuit (bad CVE-ID format) unaffected

Suite delta: 902 → 920 passing (+18), 0 failures


Open PRs checked — no overlap

Confirmed no duplicate work against all open PRs:
#51, #53, #54, #58, #60, #64, #65, #67, #74, #75, #76, #77, #78, #79, #80, #82, #83, #85, #86, #87, #88, #89, #90, #91, #92, #93, #94

None of those PRs address submit_cves exception safety or get_github_advisory ValueError handling.

…dvisory

Two real exception-safety bugs, found by previous test suites and evolution log:

Bug 1 — submit_cves (ValueError escapes try/except):
  The raise ValueError(...) for a missing CVE_SUBMIT_URL was placed *outside*
  the try/except block, so callers received a raw ValueError instead of the
  expected {status: "error"} dict.  Fix: move URL resolution, validation, and
  the raise inside the existing try block so the broad `except Exception`
  handler catches it and returns a proper error response.

Bug 2 — get_github_advisory (ValueError missing from except clause):
  The final except clause only listed (KeyError, IndexError), omitting
  ValueError.  response.json() raises ValueError (and its subclass
  json.JSONDecodeError) on malformed response bodies — these escaped silently.
  Fix: expand clause to except (KeyError, IndexError, ValueError).

Tests (tests/test_bug_fixes.py — 18 new tests, 0 failures):
  - submit_cves: missing-URL returns error status, never raises, toolUseId
    preserved, error text mentions config key, happy path (URL via env + config)
    still calls requests.post and returns success, HTTPError/ConnectionError
    still caught
  - get_github_advisory: ValueError/JSONDecodeError caught and returned as
    error dict, JSONDecodeError subclass caught, IndexError still caught,
    HTTP 404 still returns not-found message, happy path unaffected, input
    validation still short-circuits

Suite delta: 902 → 920 passing (+18), 0 failures
@manus-use
manus-use merged commit d95dfb5 into main Jul 5, 2026
3 checks passed
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.

1 participant