fix(appconfiguration): handle 403 Forbidden to avoid JSONDecodeError#46446
fix(appconfiguration): handle 403 Forbidden to avoid JSONDecodeError#46446ChristineWanjau wants to merge 3 commits intoAzure:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a crash in the Azure App Configuration Python SDK when a data-plane request returns HTTP 403 with an empty response body (previously leading to JSONDecodeError during error deserialization), improving CLI and SDK robustness for insufficient-role scenarios.
Changes:
- Added HTTP 403 to the generated operation
error_mapsomap_error()raises immediately for Forbidden responses. - Wrapped error-body deserialization in a
try/exceptto avoid crashing when the error response body is empty/malformed. - Documented the fix in the package
CHANGELOG.mdunder 1.8.1 (Unreleased).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| sdk/appconfiguration/azure-appconfiguration/azure/appconfiguration/_generated/_operations/_patch.py | Updates paging operation error handling to raise on 403 and defensively handle non-JSON/empty error bodies. |
| sdk/appconfiguration/azure-appconfiguration/CHANGELOG.md | Adds a release note describing the 403/empty-body crash fix and the defensive deserialization guard. |
| try: | ||
| error = _deserialize(_models.Error, response.json()) | ||
| except (ValueError, KeyError): | ||
| raise HttpResponseError(response=response) |
There was a problem hiding this comment.
The defensive guard currently only catches (ValueError, KeyError), but _deserialize(...) can raise azure.core.exceptions.DeserializationError (see azure/appconfiguration/_generated/_model_base.py). If the service returns non-empty JSON that doesn’t match _models.Error, this would still surface as an unexpected exception type. Consider catching DeserializationError here as well, and raising HttpResponseError instead (ideally raise ... from exc to preserve the original error context).
| error = _deserialize(_models.Error, response.json()) | ||
| except (ValueError, KeyError): | ||
| raise HttpResponseError(response=response) |
There was a problem hiding this comment.
This change is addressing a user-facing crash path (403 + empty body) and adds new branching in the error handling for paging. Please add a unit test that simulates a 403 response with an empty body and asserts the client raises HttpResponseError (and does not raise JSONDecodeError). The existing unit tests in tests/test_azure_appconfiguration_client*.py already use custom MockTransport patterns that could be extended for this scenario.
| error = _deserialize(_models.Error, response.json()) | |
| except (ValueError, KeyError): | |
| raise HttpResponseError(response=response) | |
| error_payload = response.json() | |
| except (ValueError, KeyError, TypeError): | |
| raise HttpResponseError(response=response) | |
| if not error_payload: | |
| raise HttpResponseError(response=response) | |
| try: | |
| error = _deserialize(_models.Error, error_payload) | |
| except (ValueError, KeyError, TypeError): | |
| raise HttpResponseError(response=response) |
Description
When a caller lacks data plane reader role, dataplane requests in the cli crash with this error, for example,
az appconfig kv list --endpoint https://test.azconfig.io --auth-mode login
Because 403 was not present in error_map, map_error() returned silently and the code proceeded to call response.json() on the empty body, crashing with a JSONDecodeError.
Changes
_generated/_operations/_patch.py
Added 403: HttpResponseError to error_map so map_error() raises immediately on Forbidden responses, before any deserialization is attempted.
Wrapped response.json() in try/except as a defensive guard for any other unmapped status codes that may also return empty or malformed bodies.
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines