Skip to content

fix(http-client-python): raise azure-core error types for customized errors covering standard status codes#11250

Open
l0lawrence wants to merge 2 commits into
mainfrom
python-custom-error-status-mapping-upstream
Open

fix(http-client-python): raise azure-core error types for customized errors covering standard status codes#11250
l0lawrence wants to merge 2 commits into
mainfrom
python-custom-error-status-mapping-upstream

Conversation

@l0lawrence

Copy link
Copy Markdown
Member

Problem

When a TypeSpec operation declares a customized error model that covers one of the standard azure-core status codes (401, 404, 409, 304), the Python emitter did not consistently raise the dedicated azure-core error type:

  • Ranged custom error (e.g. 4XX) covering a standard code → fell through to a generic HttpResponseError.
  • Default custom error model (covers all non-success codes) → likewise fell through to HttpResponseError for the standard codes.

Only a custom error targeting a standard code specifically raised the dedicated type, so behavior was inconsistent across the single / ranged / default cases.

Fix

Standard status codes now always map to their dedicated azure-core error type via the operation error_map, regardless of whether a customized error model (single, ranged, or default) also covers them:

  • 401 → ClientAuthenticationError
  • 404 → ResourceNotFoundError
  • 409 → ResourceExistsError
  • 304 → ResourceNotModifiedError

Because map_error(status_code=..., response=..., error_map=error_map) runs first in the generated handler, these codes raise their dedicated type there. The customized error body continues to be deserialized and attached (model=error) to the generic HttpResponseError that is raised for any other (non-standard) status codes covered by the customized error.

Behavior change note

For a custom error that targets a standard code specifically (e.g. a 404 model), the dedicated error is still raised, but the deserialized custom body is no longer attached to it — map_error raises before deserialization, so exc.model is None for those codes. The body remains available on HttpResponseError for non-standard codes. The response-status-code-range mock-api tests were updated to reflect this.

Example generated output (ranged custom error + default custom error)

if response.status_code not in [204]:
    map_error(status_code=response.status_code, response=response, error_map=error_map)
    error = None
    if 494 <= response.status_code <= 499:
        error = _failsafe_deserialize(_models.ErrorInRange, response)
    else:
        error = _failsafe_deserialize(_models.DefaultError, response)
    raise HttpResponseError(response=response, model=error)

with the shared error map:

error_map: MutableMapping = {
    401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError,
    304: ResourceNotModifiedError,
}

Validation

  • Regenerated all Azure + unbranded spector specs (181 specs, 0 failures).
  • response-status-code-range mock-api tests pass (sync + async, 4/4), exercising both an in-range code and the single 404 → ResourceNotFoundError.
  • Added a fix changelog entry for @typespec/http-client-python.

…errors covering standard status codes

Always populate the operation error_map with the standard azure-core error types (401 -> ClientAuthenticationError, 404 -> ResourceNotFoundError, 409 -> ResourceExistsError, 304 -> ResourceNotModifiedError), even when a customized error model covers those status codes via a ranged or default error response. map_error then raises the dedicated error type instead of falling back to a generic HttpResponseError. The customized error body continues to be deserialized and attached to the HttpResponseError raised for other (non-standard) status codes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:python Issue for the Python client emitter: @typespec/http-client-python label Jul 14, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-python@11250

commit: 6b04625

@github-actions

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @typespec/http-client-python
Show changes

@typespec/http-client-python - fix ✏️

Always populate the operation error_map with the standard azure-core error types (401 → ClientAuthenticationError, 404 → ResourceNotFoundError, 409 → ResourceExistsError, 304 → ResourceNotModifiedError), even when a customized error model covers those status codes. Previously, a standard status code covered by a customized ranged or default error model fell back to a generic HttpResponseError; it now raises its dedicated error type via map_error. The customized error body continues to be deserialized and attached to the HttpResponseError raised for other (non-standard) status codes.

@azure-sdk-automation

azure-sdk-automation Bot commented Jul 14, 2026

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@l0lawrence

Copy link
Copy Markdown
Member Author

Diff is Azure/azure-sdk-for-python#48056

@msyyc msyyc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ever discussed about it in teams channel and the breaking of spector case could be accepted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:python Issue for the Python client emitter: @typespec/http-client-python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants