Skip to content

fix(extensions,presets): surface clean error on malformed download URL#3577

Open
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/download-url-malformed-valueerror
Open

fix(extensions,presets): surface clean error on malformed download URL#3577
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/download-url-malformed-valueerror

Conversation

@Noor-ul-ain001

Copy link
Copy Markdown
Contributor

Summary

ExtensionCatalog.download_extension and PresetCatalog.download_pack read a download_url from catalog payload data and pass it through urlparse(...).hostname during their HTTPS validation. A malformed authority — e.g. an unterminated IPv6 bracket like https://[::1, or https://[not-an-ip]/x — makes urlparse/.hostname raise a raw ValueError.

That ValueError escapes the command handlers, which only catch ExtensionError / PresetError, so instead of a clean CLI message the user gets an uncaught traceback.

This wraps the parse in a try/except ValueError and re-raises as the module's domain error (ExtensionError / PresetError) with a clear "download URL is malformed" message.

Bug class

Same shape as the already-fixed unguarded-urlparse leaks in:

This closes the two remaining sibling code paths (extensions + presets) that had the same latent crash.

Changes

  • src/specify_cli/extensions/__init__.py — guard the download_url parse in download_extension.
  • src/specify_cli/presets/__init__.py — guard the download_url parse in download_pack.
  • tests/test_extensions.py — regression test asserting a malformed URL raises ExtensionError (not ValueError).
  • tests/test_presets.py — matching regression test for download_pack.

Testing

  • New tests fail on the pre-fix source (raw ValueError) and pass with the guard ("test-the-test" verified).
  • Full tests/test_extensions.py and tests/test_presets.py pass (717 passed, 5 skipped).

🤖 Generated with Claude Code

`ExtensionCatalog.download_extension` and `PresetCatalog.download_pack` read
`download_url` from catalog payload data and pass it to `urlparse(...).hostname`
during the HTTPS validation. A malformed authority (e.g. an unterminated IPv6
bracket like `https://[::1`) makes urlparse/hostname raise a raw `ValueError`,
which escapes past the command handlers — they only catch `ExtensionError` /
`PresetError` — and surfaces as an uncaught traceback.

Guard the parse in a try/except and re-raise as the domain error so the CLI
reports a clean "download URL is malformed" message. Mirrors the same fix in
catalogs (github#3435) and workflows/catalog.py (github#3484).

Adds regression coverage for both catalogs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Noor-ul-ain001
Noor-ul-ain001 requested a review from mnriem as a code owner July 17, 2026 05:47
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