Microsoft Azure Core Library providing foundational infrastructure for Azure SDK Python clients
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Azure Core provides a comprehensive exception hierarchy designed to handle various error conditions that can occur when interacting with Azure services. The exception system enables consistent error handling across all Azure SDK clients.
All Azure Core exceptions inherit from the base AzureError class, providing a consistent interface for error handling.
from azure.core.exceptions import AzureError
class AzureError(Exception):
"""Base exception for all Azure SDK errors."""
def __init__(self, message: str = None, **kwargs): ...
@property
def message(self) -> str: ...
@property
def error(self) -> Optional[object]: ...
@property
def continuation_token(self) -> Optional[str]: ...Errors that occur during HTTP request preparation and response processing.
from azure.core.exceptions import ServiceRequestError, ServiceResponseError, HttpResponseError
class ServiceRequestError(AzureError):
"""Error occurred during request preparation."""
def __init__(self, message: str = None, **kwargs): ...
class ServiceResponseError(AzureError):
"""Error occurred during response processing."""
def __init__(self, message: str = None, **kwargs): ...
class HttpResponseError(AzureError):
"""HTTP response error with status code information."""
def __init__(self, message: str = None, response: HttpResponse = None, **kwargs): ...
@property
def status_code(self) -> Optional[int]: ...
@property
def response(self) -> Optional[HttpResponse]: ...
@property
def reason(self) -> Optional[str]: ...Specialized exceptions for common HTTP status codes and error conditions.
from azure.core.exceptions import (
ResourceExistsError, ResourceNotFoundError, ResourceModifiedError,
ResourceNotModifiedError, ClientAuthenticationError
)
class ResourceExistsError(HttpResponseError):
"""Resource already exists error (typically 409)."""
pass
class ResourceNotFoundError(HttpResponseError):
"""Resource not found error (404/412)."""
pass
class ResourceModifiedError(HttpResponseError):
"""Resource was modified error (412 with etag mismatch)."""
pass
class ResourceNotModifiedError(HttpResponseError):
"""Resource not modified error (304)."""
pass
class ClientAuthenticationError(HttpResponseError):
"""Authentication error (401/403)."""
passErrors related to network connectivity and HTTP transport.
from azure.core.exceptions import (
TooManyRedirectsError, ServiceRequestTimeoutError, ServiceResponseTimeoutError,
IncompleteReadError
)
class TooManyRedirectsError(ServiceRequestError):
"""Maximum redirect attempts exceeded."""
def __init__(self, history: Optional[List] = None, **kwargs): ...
@property
def history(self) -> Optional[List]: ...
class ServiceRequestTimeoutError(ServiceRequestError):
"""Service request timeout error."""
pass
class ServiceResponseTimeoutError(ServiceResponseError):
"""Service response timeout error."""
pass
class IncompleteReadError(ServiceResponseError):
"""Incomplete read error during response processing."""
passErrors related to request/response stream handling and content processing.
from azure.core.exceptions import (
StreamConsumedError, StreamClosedError, ResponseNotReadError
)
class StreamConsumedError(AzureError):
"""Stream has already been consumed and cannot be read again."""
pass
class StreamClosedError(AzureError):
"""Stream has been closed and cannot be accessed."""
pass
class ResponseNotReadError(AzureError):
"""Response content has not been read yet."""
passErrors that occur during data serialization and deserialization.
from azure.core.exceptions import SerializationError, DeserializationError, DecodeError
class SerializationError(AzureError):
"""Error occurred during data serialization."""
pass
class DeserializationError(AzureError):
"""Error occurred during data deserialization."""
pass
class DecodeError(ServiceResponseError):
"""Response content decoding error."""
passSupport for OData V4 error format parsing commonly used by Azure services.
from azure.core.exceptions import ODataV4Format, ODataV4Error
class ODataV4Format:
"""OData V4 error format parser."""
@staticmethod
def deserialize(response: HttpResponse) -> Dict: ...
class ODataV4Error(HttpResponseError):
"""OData V4 formatted error response."""
def __init__(self, response: HttpResponse, **kwargs): ...
@property
def code(self) -> Optional[str]: ...
@property
def details(self) -> Optional[List[Dict]]: ...Utilities for mapping HTTP status codes to appropriate exception types.
from azure.core.exceptions import map_error
from typing import Dict, Type, Callable
def map_error(
status_code: int,
response: HttpResponse,
error_map: Optional[Dict[int, Type[HttpResponseError]]] = None
) -> None:
"""Map HTTP status codes to exception types and raise appropriate error."""
...
# Deprecated utility function
def raise_with_traceback(exception: Exception, traceback=None) -> None:
"""Raise exception with traceback (deprecated)."""
...from azure.core.exceptions import AzureError, HttpResponseError, ResourceNotFoundError
from azure.core import PipelineClient
try:
client = PipelineClient(base_url="https://api.example.com")
# Make request...
except ResourceNotFoundError as e:
print(f"Resource not found: {e.message}")
print(f"Status code: {e.status_code}")
except HttpResponseError as e:
print(f"HTTP error: {e.status_code} - {e.reason}")
except AzureError as e:
print(f"Azure error: {e.message}")
except Exception as e:
print(f"Unexpected error: {e}")from azure.core.exceptions import map_error, HttpResponseError
# Define custom error mapping
error_map = {
404: ResourceNotFoundError,
409: ResourceExistsError,
401: ClientAuthenticationError,
}
def handle_response(response):
if response.status_code >= 400:
# Use custom error mapping
map_error(response.status_code, response, error_map)
return responsefrom azure.core.exceptions import HttpResponseError, ODataV4Error
import json
try:
# Make service request...
pass
except HttpResponseError as e:
if e.response and e.response.headers.get("content-type", "").startswith("application/json"):
try:
error_details = e.response.json()
if "error" in error_details:
# Handle OData error format
error_code = error_details["error"].get("code")
error_message = error_details["error"].get("message")
print(f"Service error {error_code}: {error_message}")
else:
print(f"Service returned error: {error_details}")
except (json.JSONDecodeError, KeyError):
print(f"Non-JSON error response: {e.message}")
else:
print(f"HTTP error {e.status_code}: {e.reason}")from azure.core.exceptions import AzureError, ServiceRequestError
import time
import random
def retry_with_backoff(func, max_retries=3, base_delay=1.0):
"""Retry function with exponential backoff."""
for attempt in range(max_retries + 1):
try:
return func()
except (ServiceRequestError, ConnectionError) as e:
if attempt == max_retries:
raise e
delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
print(f"Attempt {attempt + 1} failed, retrying in {delay:.2f}s...")
time.sleep(delay)
except AzureError:
# Don't retry on non-transient Azure errors
raise
# Usage
def make_request():
# Your request logic here
pass
try:
result = retry_with_backoff(make_request, max_retries=5)
except AzureError as e:
print(f"Request failed after all retries: {e}")from azure.core.exceptions import StreamConsumedError, StreamClosedError
def read_stream_safely(response):
try:
# Read stream content
content = response.content
return content
except StreamConsumedError:
print("Stream has already been consumed")
return None
except StreamClosedError:
print("Stream has been closed")
return None
def read_stream_multiple_times(response):
"""Example of handling stream consumption."""
try:
# First read
content1 = response.text
# Second read will fail
content2 = response.text
except StreamConsumedError:
print("Cannot read stream multiple times without reopening")
# Would need to make a new request to get content againimport asyncio
from azure.core.exceptions import AzureError, HttpResponseError
async def async_request_with_error_handling():
try:
# Make async request...
pass
except HttpResponseError as e:
print(f"Async HTTP error: {e.status_code}")
# Handle specific async error conditions
if e.status_code == 429: # Rate limited
# Wait before retrying
await asyncio.sleep(1)
except AzureError as e:
print(f"Async Azure error: {e.message}")
# asyncio.run(async_request_with_error_handling())Many Azure services return errors in OData V4 format:
{
"error": {
"code": "InvalidResourceName",
"message": "The specified resource name contains invalid characters.",
"details": [
{
"code": "InvalidCharacter",
"message": "Character '@' is not allowed in resource names.",
"target": "resourceName"
}
]
}
}from azure.core.exceptions import ODataV4Format
def parse_odata_error(response):
if response.headers.get("content-type", "").startswith("application/json"):
error_data = ODataV4Format.deserialize(response)
if error_data:
main_error = error_data.get("error", {})
code = main_error.get("code")
message = main_error.get("message")
details = main_error.get("details", [])
print(f"Error code: {code}")
print(f"Error message: {message}")
for detail in details:
print(f"Detail: {detail.get('message')} (target: {detail.get('target')})")AzureError as a fallback for Azure SDK specific errorsresponse property of HttpResponseError to access full response detailscontinuation_token property for resumable operationsInstall with Tessl CLI
npx tessl i tessl/pypi-azure-coredocs