from typing import Any, Dict, Optional, Tuple from litellm.exceptions import ContentPolicyViolationError class AzureOpenAIExceptionMapping: """ Class for creating Azure OpenAI specific exceptions """ @staticmethod def create_content_policy_violation_error( message: str, model: str, extra_information: str, original_exception: Exception, ) -> ContentPolicyViolationError: """ Create a content policy violation error """ azure_error, inner_error = AzureOpenAIExceptionMapping._extract_azure_error( original_exception ) # Prefer the provider message/type/code when present. provider_message = ( azure_error.get("message") if isinstance(azure_error, dict) else None ) or message provider_type = ( azure_error.get("type") if isinstance(azure_error, dict) else None ) provider_code = ( azure_error.get("code") if isinstance(azure_error, dict) else None ) # Keep the OpenAI-style body fields populated so downstream (proxy + SDK) # can surface `type` / `code` correctly. openai_style_body: Dict[str, Any] = { "message": provider_message, "type": provider_type or "invalid_request_error", "code": provider_code or "content_policy_violation", "param": None, } raise ContentPolicyViolationError( message=provider_message, llm_provider="azure", model=model, litellm_debug_info=extra_information, response=getattr(original_exception, "response", None), provider_specific_fields={ # Preserve legacy key for backward compatibility. "innererror": inner_error, # Prefer Azure's current naming. "inner_error": inner_error, # Include the full Azure error object for clients that want it. "azure_error": azure_error or None, }, body=openai_style_body, ) @staticmethod def _extract_azure_error( original_exception: Exception, ) -> Tuple[Dict[str, Any], Optional[dict]]: """Extract Azure OpenAI error payload and inner error details. Azure error formats can vary by endpoint/version. Common shapes: - {"innererror": {...}} (legacy) - {"error": {"code": "...", "message": "...", "type": "...", "inner_error": {...}}} - {"code": "...", "message": "...", "type": "..."} (already flattened) """ body_dict = getattr(original_exception, "body", None) or {} if not isinstance(body_dict, dict): return {}, None # Some SDKs place the payload under "error". azure_error: Dict[str, Any] if isinstance(body_dict.get("error"), dict): azure_error = body_dict.get("error", {}) # type: ignore[assignment] else: azure_error = body_dict inner_error = ( azure_error.get("inner_error") or azure_error.get("innererror") or body_dict.get("innererror") or body_dict.get("inner_error") ) return azure_error, inner_error