Add SEO fields to Tasks model, improve content generation response handling, and enhance progress bar animation
- Added primary_keyword, secondary_keywords, tags, and categories fields to Tasks model - Updated generate_content function to handle full JSON response with all SEO fields - Improved progress bar animation: smooth 1% increments every 300ms - Enhanced step detection for content generation vs clustering vs ideas - Fixed progress modal to show correct messages for each function type - Added comprehensive logging to Keywords and Tasks pages for AI functions - Fixed error handling to show meaningful error messages instead of generic failures
This commit is contained in:
@@ -777,25 +777,72 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
try:
|
||||
task_state = task.state
|
||||
except (ValueError, KeyError) as state_exc:
|
||||
# Task has malformed exception info - try to get error from result
|
||||
# Task has malformed exception info - try to get error from multiple sources
|
||||
logger.warning(f"Error accessing task.state (malformed exception info): {str(state_exc)}")
|
||||
error_msg = 'Task failed - exception details unavailable'
|
||||
error_type = 'UnknownError'
|
||||
request_steps = []
|
||||
response_steps = []
|
||||
|
||||
# First, try to get from backend's stored meta (most reliable for our update_state calls)
|
||||
try:
|
||||
# Try to get error from task.result
|
||||
if hasattr(task, 'result'):
|
||||
result = task.result
|
||||
if isinstance(result, dict) and 'error' in result:
|
||||
error_msg = result['error']
|
||||
elif isinstance(result, str):
|
||||
error_msg = result
|
||||
except Exception:
|
||||
pass
|
||||
backend = task.backend
|
||||
if hasattr(backend, 'get_task_meta'):
|
||||
stored_meta = backend.get_task_meta(task_id)
|
||||
if stored_meta and isinstance(stored_meta, dict):
|
||||
meta = stored_meta.get('meta', {})
|
||||
if isinstance(meta, dict):
|
||||
if 'error' in meta:
|
||||
error_msg = meta.get('error')
|
||||
if 'error_type' in meta:
|
||||
error_type = meta.get('error_type', error_type)
|
||||
if 'request_steps' in meta:
|
||||
request_steps = meta.get('request_steps', [])
|
||||
if 'response_steps' in meta:
|
||||
response_steps = meta.get('response_steps', [])
|
||||
except Exception as e:
|
||||
logger.debug(f"Error getting from backend meta: {str(e)}")
|
||||
|
||||
# Try to get error from task.result
|
||||
if error_msg == 'Task failed - exception details unavailable':
|
||||
try:
|
||||
if hasattr(task, 'result'):
|
||||
result = task.result
|
||||
if isinstance(result, dict):
|
||||
error_msg = result.get('error', error_msg)
|
||||
error_type = result.get('error_type', error_type)
|
||||
request_steps = result.get('request_steps', request_steps)
|
||||
response_steps = result.get('response_steps', response_steps)
|
||||
elif isinstance(result, str):
|
||||
error_msg = result
|
||||
except Exception as e:
|
||||
logger.debug(f"Error extracting error from task.result: {str(e)}")
|
||||
|
||||
# Also try to get error from task.info
|
||||
if error_msg == 'Task failed - exception details unavailable':
|
||||
try:
|
||||
if hasattr(task, 'info') and task.info:
|
||||
if isinstance(task.info, dict):
|
||||
if 'error' in task.info:
|
||||
error_msg = task.info['error']
|
||||
if 'error_type' in task.info:
|
||||
error_type = task.info['error_type']
|
||||
if 'request_steps' in task.info:
|
||||
request_steps = task.info.get('request_steps', request_steps)
|
||||
if 'response_steps' in task.info:
|
||||
response_steps = task.info.get('response_steps', response_steps)
|
||||
except Exception as e:
|
||||
logger.debug(f"Error extracting error from task.info: {str(e)}")
|
||||
|
||||
return Response({
|
||||
'state': 'FAILURE',
|
||||
'meta': {
|
||||
'error': error_msg,
|
||||
'error_type': error_type,
|
||||
'percentage': 0,
|
||||
'message': f'Error: {error_msg}',
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps,
|
||||
}
|
||||
})
|
||||
except (KombuOperationalError, RedisConnectionError, ConnectionError) as conn_exc:
|
||||
@@ -834,15 +881,29 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
})
|
||||
|
||||
# Safely get task info/result
|
||||
# Try to get error from task.result first (before it gets malformed)
|
||||
# Try to get error from multiple sources
|
||||
task_result = None
|
||||
task_info = None
|
||||
error_message = None
|
||||
error_type = None
|
||||
|
||||
# First, try to get from backend's stored meta (most reliable for our update_state calls)
|
||||
try:
|
||||
backend = task.backend
|
||||
if hasattr(backend, 'get_task_meta'):
|
||||
stored_meta = backend.get_task_meta(task_id)
|
||||
if stored_meta and isinstance(stored_meta, dict):
|
||||
meta = stored_meta.get('meta', {})
|
||||
if isinstance(meta, dict):
|
||||
if 'error' in meta:
|
||||
error_message = meta.get('error')
|
||||
error_type = meta.get('error_type', 'UnknownError')
|
||||
except Exception as backend_err:
|
||||
logger.debug(f"Could not get from backend meta: {backend_err}")
|
||||
|
||||
try:
|
||||
# Try to get result first - this often has the actual error
|
||||
if hasattr(task, 'result'):
|
||||
if not error_message and hasattr(task, 'result'):
|
||||
try:
|
||||
task_result = task.result
|
||||
# If result is a dict with error, extract it
|
||||
@@ -850,6 +911,9 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
if 'error' in task_result:
|
||||
error_message = task_result.get('error')
|
||||
error_type = task_result.get('error_type', 'UnknownError')
|
||||
elif 'success' in task_result and not task_result.get('success'):
|
||||
error_message = task_result.get('error', 'Task failed')
|
||||
error_type = task_result.get('error_type', 'UnknownError')
|
||||
except Exception:
|
||||
pass # Will try task.info next
|
||||
except Exception:
|
||||
@@ -971,6 +1035,25 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
else:
|
||||
error_message = str(error_info) if error_info else 'Task failed'
|
||||
|
||||
# If still no error message, try to get from task backend directly
|
||||
if not error_message:
|
||||
try:
|
||||
# Try to get from backend's stored result
|
||||
backend = task.backend
|
||||
if hasattr(backend, 'get'):
|
||||
stored = backend.get(task_id)
|
||||
if stored and isinstance(stored, dict):
|
||||
if 'error' in stored:
|
||||
error_message = stored['error']
|
||||
elif isinstance(stored.get('result'), dict) and 'error' in stored['result']:
|
||||
error_message = stored['result']['error']
|
||||
except Exception as backend_err:
|
||||
logger.warning(f"Error getting from backend: {backend_err}")
|
||||
|
||||
# Final fallback
|
||||
if not error_message:
|
||||
error_message = 'Task failed - check backend logs for details'
|
||||
|
||||
response_meta = {
|
||||
'error': error_message,
|
||||
'percentage': 0,
|
||||
@@ -992,6 +1075,13 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
# Also include error_type if available in meta
|
||||
if 'error_type' in meta and not error_type:
|
||||
response_meta['error_type'] = meta['error_type']
|
||||
# Also check for error in meta directly
|
||||
if 'error' in meta and not error_message:
|
||||
error_message = meta['error']
|
||||
response_meta['error'] = error_message
|
||||
if 'error_type' in meta and not error_type:
|
||||
error_type = meta['error_type']
|
||||
response_meta['error_type'] = error_type
|
||||
|
||||
return Response({
|
||||
'state': task_state,
|
||||
|
||||
Reference in New Issue
Block a user