Skip to content

fix(salesforce-api): #3939 preserve native MDAPI exception types in BaseMetadataApiCall#3984

Draft
jstvz wants to merge 2 commits into
devfrom
triage/fix-tranche1-3939
Draft

fix(salesforce-api): #3939 preserve native MDAPI exception types in BaseMetadataApiCall#3984
jstvz wants to merge 2 commits into
devfrom
triage/fix-tranche1-3939

Conversation

@jstvz
Copy link
Copy Markdown
Contributor

@jstvz jstvz commented May 14, 2026

Summary

Fixes #3939.

BaseMetadataApiCall.__call__ wrapped all exceptions in a generic except Exception clause, including MetadataApiError and ApexTestException, hiding the structured detail that downstream code relies on (component failures, test failure summaries, etc.).

The fix narrows the except clause: MetadataApiError and ApexTestException propagate untouched, while truly unexpected errors are still wrapped as before.

Test plan

  • cumulusci/salesforce_api/tests/test_metadata.py::TestCallExceptionPropagation 4 tests pass (new).
  • xfail marker on cumulusci/tests/triage/test_issue_3939.py removed in the GREEN commit; test now passes.
  • uv run pytest cumulusci/salesforce_api/tests/test_metadata.py -q clean.

Provenance

Reproduced and characterized in the v5 triage evidence pack (PR #3979). See docs/triage/v5/repro-results.md (### #3939) for the full narrative.

Companion to #3938 (same author, same day, same task family; REST-side raise-on-failure).

jstvz added 2 commits May 14, 2026 10:57
…ons propagate untouched

Adds TestCallExceptionPropagation covering BaseMetadataApiCall.__call__
exception handling. Three tests demonstrate that ApexTestException,
MetadataApiError, and MetadataComponentFailure raised inside
_process_response are currently masked by MetadataParseError; a fourth
test pins the safety-net behavior that genuinely unexpected exceptions
(e.g. KeyError from XML parsing) should still be wrapped.

These tests fail on unmodified source; the fix follows in the next
commit.
…iCall to preserve native exception types

`BaseMetadataApiCall.__call__` previously wrapped EVERY exception
raised inside `_process_response` as
`MetadataParseError("Could not process MDAPI response: ...")`. This
masked CumulusCI's own legitimate failure exceptions:
`MetadataApiError`, `MetadataComponentFailure` (subclass of
`MetadataApiError`), and `ApexTestException`: all of which
`_process_response` raises intentionally on real deploy/test failures.

Users running deploy tasks saw messages like
"Could not process MDAPI response: Apex Test Failure: ..."
instead of the underlying `ApexTestException`, breaking exception-type
based handling downstream and adding noisy prefix to error reports.

Narrow the except clause: native CumulusCI exception types
re-raise untouched; only genuinely unexpected exceptions (e.g.
KeyError/ValueError from malformed XML parsing) are still wrapped as
`MetadataParseError`, preserving the safety net. The new wrap uses
`raise ... from e` to preserve the cause chain for diagnostics.

Catching `MetadataApiError` covers `MetadataComponentFailure` and
`MetadataParseError` (both subclasses); `ApexTestException` is caught
explicitly because it inherits from `CumulusCIFailure`, not from
`MetadataApiError`.

Regression test added in the previous commit. Full
`cumulusci/salesforce_api/` suite passes (296 tests, zero new
failures).
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