eschutho opened a new pull request, #42426:
URL: https://github.com/apache/superset/pull/42426

   ### SUMMARY
   `load_yaml()` in `superset/commands/importers/v1/utils.py` only caught 
`yaml.parser.ParserError`, missing sibling exceptions under 
`yaml.error.YAMLError` (`ScannerError`, `ComposerError`, `ReaderError`, 
`ConstructorError`). A raw error from these classes propagated as an unhandled 
500 instead of the intended `ValidationError` → `CommandInvalidError` (422) 
with a clear "Not a valid YAML file" message. This mirrors the same bug class 
fixed in #42366 and #42401, and this file already has a sibling call site 
(`import_tag()`) that catches the broader `yaml.YAMLError` correctly — this PR 
brings `load_yaml()` in line with that existing pattern.
   
   ### PROBLEM
   `load_yaml()` is used by `load_metadata()` and `load_configs()` to parse 
every YAML file in an import ZIP (databases, dashboards, charts, datasets, SSH 
tunnels). It only catches `yaml.parser.ParserError`:
   ```python
   try:
       return yaml.safe_load(content)
   except yaml.parser.ParserError as ex:
       ...
       raise ValidationError({file_name: "Not a valid YAML file"}) from ex
   ```
   But `yaml.parser.ParserError`, `yaml.scanner.ScannerError`, 
`yaml.composer.ComposerError`, and others are siblings — all direct/indirect 
subclasses of `yaml.error.YAMLError`, not of each other. For example, 
`yaml.safe_load('key: "unterminated string')` raises 
`yaml.scanner.ScannerError`, which is not caught here.
   
   This is reachable end-to-end: `load_configs()` runs inside 
`ImportModelsCommand.validate()`, called from `run()` *before* the try/except 
that wraps `_import()`, so nothing in the command layer catches a leaked 
exception. The API layer (e.g. `dashboards/api.py` `import_`, and the 
chart/dataset/database equivalents) has no try/except around `command.run()` 
either — it relies only on Flask-AppBuilder's `@safe` decorator, which turns 
any uncaught exception into an opaque generic 500, discarding the actual 
reason. So importing a dashboard/chart/dataset/database ZIP with a YAML file 
that's malformed in a way other than a `ParserError` currently surfaces as an 
opaque 500 instead of a proper validation error.
   
   ### FIX
   Widen the `except` clause in `load_yaml()` to `except yaml.YAMLError as 
ex:`, matching the already-correct sibling catch in `import_tag()` in this same 
file. No other exception handling was touched; the deprecated v0 importer 
(`superset/commands/dataset/importers/v0.py`) has the same narrow-catch pattern 
but is out of scope for this PR.
   
   ### TESTING INSTRUCTIONS
   - Added `TestLoadYaml` to 
`tests/unit_tests/commands/importers/v1/utils_test.py` with two tests: one 
confirming the existing `ParserError` path still raises `ValidationError`, and 
one confirming a `ScannerError`-triggering input (`'key: "unterminated 
string'`) now also raises `ValidationError` instead of leaking the raw 
`yaml.scanner.ScannerError`.
   - Verified via `git stash` that the new `ScannerError` test fails on pre-fix 
code (`yaml.scanner.ScannerError` uncaught) and passes after the fix.
   - Ran `pytest tests/unit_tests/commands/importers/v1/utils_test.py` — 8 
passed, no regressions to the existing `TestConvertTemporalColumns` tests.
   - Ran `ruff check`, `ruff format --check`, and `mypy` on both changed files 
— no new issues.
   
   ### ADDITIONAL INFORMATION
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to