[monitor opentelemetry exporter] Handle ServiceResponseError as retryable to prevent telemetry loss#47870
Conversation
ServiceResponseError (e.g. read timeout) was not caught by the exporter's _transmit method. Since ServiceResponseError and ServiceRequestError are sibling classes (both extend AzureError directly), a read timeout fell through to the generic 'except Exception' handler, which marked the batch as FAILED_NOT_RETRYABLE — permanently dropping the telemetry instead of persisting it to local storage for retry. This change adds ServiceResponseError to the import and catch chain, treating it as FAILED_RETRYABLE so that envelopes are written to disk and retried on the next successful export cycle, consistent with the existing ServiceRequestError handling and the azure-core docstring which states these errors 'can be retried for idempotent or safe operations'.
There was a problem hiding this comment.
Pull request overview
This PR fixes a telemetry-loss bug in the Azure Monitor OpenTelemetry Exporter. Previously, a ServiceResponseError (e.g. a read timeout) fell through to the generic except Exception handler in BaseExporter._transmit(), which marked the batch as FAILED_NOT_RETRYABLE and permanently dropped the telemetry. The change adds a dedicated ServiceResponseError handler that classifies it as FAILED_RETRYABLE, so envelopes are persisted to local offline storage and retried, consistent with the existing ServiceRequestError handling and the azure-core guidance that these errors are safe to retry.
Changes:
- Add
ServiceResponseErrorto the import and exception chain in_transmit(), treating it asFAILED_RETRYABLEand mirroring the existing statsbeat and customer-sdkstats tracking done forServiceRequestError. - Add unit tests for the retryable result and statsbeat exception counting on
ServiceResponseError. - Add a customer-sdkstats test verifying
track_retry_itemsis invoked onServiceResponseError.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
azure/monitor/opentelemetry/exporter/export/_base.py |
Adds ServiceResponseError import and a new retryable except branch (with statsbeat + customer-sdkstats tracking) placed before the generic Exception handler. |
tests/test_base_exporter.py |
Adds test_transmit_response_error and test_transmit_response_error_statsbeat mirroring the existing ServiceRequestError tests. |
tests/test_base_customer_sdkstats.py |
Adds test_transmit_service_response_error_customer_sdkstats_track_retry_items verifying retry tracking on ServiceResponseError. |
Note: Consider adding a CHANGELOG.md entry under the unreleased 1.0.0b56 "Bugs Fixed" section, since this package maintains per-PR changelog entries for bug fixes.
ServiceResponseError (e.g. read timeout) was not caught by the exporter's _transmit method. Since ServiceResponseError and ServiceRequestError are sibling classes (both extend AzureError directly), a read timeout fell through to the generic 'except Exception' handler, which marked the batch as FAILED_NOT_RETRYABLE — permanently dropping the telemetry instead of persisting it to local storage for retry.
This change adds ServiceResponseError to the import and catch chain, treating it as FAILED_RETRYABLE so that envelopes are written to disk and retried on the next successful export cycle, consistent with the existing ServiceRequestError handling and the azure-core docstring which states these errors 'can be retried for idempotent or safe operations'.