920ed7546d
`_local_manifest_source` handles three local bundle sources. The directory
and `bundle.yml` branches both go through `BundleManifest.from_file` ->
`load_yaml`, which converts a parse failure into a `BundlerError`. The `.zip`
branch instead parses inline with a bare `_yaml.safe_load`.
`yaml.YAMLError` derives directly from `Exception` -- it is neither a
`ValueError` nor an `OSError` -- so it escapes `bundle_install`'s
`except BundlerError` and reaches the user as a raw
`yaml.parser.ParserError` traceback.
The remote counterpart of this same call, `_download_manifest`, already
guards it and even names `_yaml.YAMLError` explicitly. Only the local zip
path was missed, so the same corrupt manifest is reported cleanly when
fetched from a catalog but crashes when installed from disk.
Before, for the identical malformed bundle.yml:
specify bundle install ./bundle-dir -> Error: Invalid YAML in ... (exit 1)
specify bundle install ./bundle.yml -> Error: Invalid YAML in ... (exit 1)
specify bundle install ./bundle.zip -> ParserError traceback
Two regression tests: one pins the `BundlerError` contract on the zip
branch, and one drives all three local sources through the CLI to assert
they now fail alike.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>