Refactor integration settings handling and error response mapping

- Simplify request data handling in the 'IntegrationSettingsViewSet' by removing unnecessary try-except blocks and improving clarity.
- Enhance API key retrieval logic with better fallback mechanisms for account settings.
- Implement detailed error mapping for OpenAI API responses, ensuring appropriate HTTP status codes are returned based on the response received.
- Update logging for improved visibility during account and settings lookups.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-16 09:55:12 +00:00
parent d3ec7cf2e3
commit 65c7fb87fa

View File

@@ -90,67 +90,48 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
) )
# Get API key and config from request or saved settings # Get API key and config from request or saved settings
# Handle empty request.data gracefully (for API monitor) config = request.data.get('config', {}) if isinstance(request.data.get('config'), dict) else {}
try: api_key = request.data.get('apiKey') or config.get('apiKey')
request_data = request.data if hasattr(request, 'data') and request.data else {}
if not isinstance(request_data, dict):
request_data = {}
except Exception:
request_data = {}
config = request_data.get('config', {}) if isinstance(request_data.get('config'), dict) else {} # Merge request.data with config if config is a dict
api_key = request_data.get('apiKey') or config.get('apiKey')
# Ensure config is a dict
if not isinstance(config, dict): if not isinstance(config, dict):
config = {} config = {}
if not api_key: if not api_key:
# Try to get from saved settings # Try to get from saved settings
account = None account = getattr(request, 'account', None)
try: logger.info(f"[test_connection] Account from request: {account.id if account else None}")
account = getattr(request, 'account', None) # Fallback to user's account
if account: if not account:
logger.info(f"[test_connection] Account from request: {account.id}") user = getattr(request, 'user', None)
# Fallback to user's account if user and hasattr(user, 'is_authenticated') and user.is_authenticated:
if not account: account = getattr(user, 'account', None)
user = getattr(request, 'user', None) # Fallback to default account
if user and hasattr(user, 'is_authenticated') and user.is_authenticated: if not account:
account = getattr(user, 'account', None) from igny8_core.auth.models import Account
if account: try:
logger.info(f"[test_connection] Account from user: {account.id}") account = Account.objects.first()
# Fallback to default account (only for API monitor/testing) except Exception:
if not account: pass
from igny8_core.auth.models import Account
try:
account = Account.objects.first()
if account:
logger.info(f"[test_connection] Using fallback account: {account.id}")
except Exception as e:
logger.debug(f"[test_connection] Could not get fallback account: {e}")
account = None
if account: if account:
try: try:
from .models import IntegrationSettings from .models import IntegrationSettings
logger.info(f"[test_connection] Looking for saved settings for account {account.id}") logger.info(f"[test_connection] Looking for saved settings for account {account.id}")
saved_settings = IntegrationSettings.objects.get( saved_settings = IntegrationSettings.objects.get(
integration_type=integration_type, integration_type=integration_type,
account=account account=account
) )
api_key = saved_settings.config.get('apiKey') if saved_settings.config else None api_key = saved_settings.config.get('apiKey')
logger.info(f"[test_connection] Found saved settings, has_apiKey={bool(api_key)}") logger.info(f"[test_connection] Found saved settings, has_apiKey={bool(api_key)}")
except IntegrationSettings.DoesNotExist: except IntegrationSettings.DoesNotExist:
logger.debug(f"[test_connection] No saved settings found for {integration_type} and account {account.id if account else 'None'}") logger.warning(f"[test_connection] No saved settings found for {integration_type} and account {account.id}")
except Exception as e: pass
logger.debug(f"[test_connection] Error getting saved settings: {e}")
except Exception as e:
logger.debug(f"[test_connection] Error during account/settings lookup: {e}")
if not api_key: if not api_key:
logger.info(f"[test_connection] No API key found in request or saved settings - returning 400 (expected for API monitor)") logger.error(f"[test_connection] No API key found in request or saved settings")
return error_response( return error_response(
error='API key is required. Please provide an API key in the request or configure it in settings.', error='API key is required',
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
request=request request=request
) )
@@ -229,7 +210,7 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
total_tokens = usage.get('total_tokens', 0) total_tokens = usage.get('total_tokens', 0)
# Calculate cost using model rates (reference plugin: line 274-275) # Calculate cost using model rates (reference plugin: line 274-275)
from igny8_core.ai.constants import MODEL_RATES from igny8_core.utils.ai_processor import MODEL_RATES
rates = MODEL_RATES.get(model, {'input': 2.00, 'output': 8.00}) rates = MODEL_RATES.get(model, {'input': 2.00, 'output': 8.00})
cost = (input_tokens * rates['input'] + output_tokens * rates['output']) / 1000000 cost = (input_tokens * rates['input'] + output_tokens * rates['output']) / 1000000
@@ -254,9 +235,25 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
) )
else: else:
body = response.text body = response.text
# Map OpenAI API errors to appropriate HTTP status codes
# OpenAI 401 (invalid API key) should be 400 (Bad Request) in our API
# OpenAI 4xx errors are client errors (invalid request) -> 400
# OpenAI 5xx errors are server errors -> 500
if response.status_code == 401:
# Invalid API key - this is a validation error, not an auth error
status_code = status.HTTP_400_BAD_REQUEST
elif 400 <= response.status_code < 500:
# Other client errors from OpenAI (invalid request, rate limit, etc.)
status_code = status.HTTP_400_BAD_REQUEST
elif response.status_code >= 500:
# Server errors from OpenAI
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
else:
status_code = response.status_code
return error_response( return error_response(
error=f'HTTP {response.status_code} {body[:200]}', error=f'HTTP {response.status_code} {body[:200]}',
status_code=response.status_code, status_code=status_code,
request=request request=request
) )
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
@@ -287,9 +284,25 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
) )
else: else:
body = response.text body = response.text
# Map OpenAI API errors to appropriate HTTP status codes
# OpenAI 401 (invalid API key) should be 400 (Bad Request) in our API
# OpenAI 4xx errors are client errors (invalid request) -> 400
# OpenAI 5xx errors are server errors -> 500
if response.status_code == 401:
# Invalid API key - this is a validation error, not an auth error
status_code = status.HTTP_400_BAD_REQUEST
elif 400 <= response.status_code < 500:
# Other client errors from OpenAI (invalid request, rate limit, etc.)
status_code = status.HTTP_400_BAD_REQUEST
elif response.status_code >= 500:
# Server errors from OpenAI
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
else:
status_code = response.status_code
return error_response( return error_response(
error=f'HTTP {response.status_code} {body[:200]}', error=f'HTTP {response.status_code} {body[:200]}',
status_code=response.status_code, status_code=status_code,
request=request request=request
) )
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e: