Spaces:
Runtime error
Runtime error

π₯ Initial DigiPal deployment to HuggingFace Spacesπ€ Generated with [Claude Code](https://claude.ai/code)Co-Authored-By: Claude <[email protected]>
4399e64
""" | |
User-friendly error messages and recovery guidance for DigiPal. | |
This module provides comprehensive user-facing error messages and | |
step-by-step recovery instructions for different error scenarios. | |
""" | |
import logging | |
from typing import Dict, List, Optional, Any | |
from enum import Enum | |
from .exceptions import DigiPalException, ErrorCategory, ErrorSeverity | |
logger = logging.getLogger(__name__) | |
class MessageTone(Enum): | |
"""Tone for error messages.""" | |
FRIENDLY = "friendly" | |
PROFESSIONAL = "professional" | |
CASUAL = "casual" | |
EMPATHETIC = "empathetic" | |
class UserErrorMessageGenerator: | |
"""Generates user-friendly error messages and recovery guidance.""" | |
def __init__(self, default_tone: MessageTone = MessageTone.FRIENDLY): | |
"""Initialize message generator.""" | |
self.default_tone = default_tone | |
self.message_templates = self._initialize_message_templates() | |
self.recovery_guides = self._initialize_recovery_guides() | |
self.contextual_messages = self._initialize_contextual_messages() | |
def _initialize_message_templates(self) -> Dict[str, Dict[MessageTone, str]]: | |
"""Initialize message templates for different tones.""" | |
return { | |
'authentication_failed': { | |
MessageTone.FRIENDLY: "Oops! We couldn't log you in. Let's get this sorted out! π", | |
MessageTone.PROFESSIONAL: "Authentication failed. Please verify your credentials.", | |
MessageTone.CASUAL: "Login didn't work. Let's try again!", | |
MessageTone.EMPATHETIC: "We understand login issues can be frustrating. Let's help you get back in." | |
}, | |
'storage_error': { | |
MessageTone.FRIENDLY: "We're having trouble saving your DigiPal's data. Don't worry, we'll fix this! πΎ", | |
MessageTone.PROFESSIONAL: "A storage error occurred. Your data may not have been saved properly.", | |
MessageTone.CASUAL: "Couldn't save your stuff. Let's figure this out.", | |
MessageTone.EMPATHETIC: "We know how important your DigiPal's progress is. Let's recover your data." | |
}, | |
'ai_model_error': { | |
MessageTone.FRIENDLY: "Your DigiPal is having trouble understanding right now. Give us a moment! π€", | |
MessageTone.PROFESSIONAL: "AI service is temporarily unavailable. Please try again shortly.", | |
MessageTone.CASUAL: "The AI is being a bit wonky. Hang tight!", | |
MessageTone.EMPATHETIC: "We know you want to chat with your DigiPal. We're working on getting them back online." | |
}, | |
'speech_processing_error': { | |
MessageTone.FRIENDLY: "I couldn't quite catch what you said. Could you try speaking again? π€", | |
MessageTone.PROFESSIONAL: "Speech recognition failed. Please ensure clear audio input.", | |
MessageTone.CASUAL: "Didn't catch that. Say it again?", | |
MessageTone.EMPATHETIC: "Sometimes speech recognition can be tricky. Let's try a different approach." | |
}, | |
'image_generation_error': { | |
MessageTone.FRIENDLY: "We're having trouble creating your DigiPal's image, but they're still there! π¨", | |
MessageTone.PROFESSIONAL: "Image generation service is unavailable. Default images will be used.", | |
MessageTone.CASUAL: "Can't make the picture right now, but your DigiPal is fine!", | |
MessageTone.EMPATHETIC: "Your DigiPal is beautiful even without a custom image. We'll try again later." | |
}, | |
'network_error': { | |
MessageTone.FRIENDLY: "Looks like there's a connection hiccup. Let's try to reconnect! π", | |
MessageTone.PROFESSIONAL: "Network connectivity issue detected. Please check your connection.", | |
MessageTone.CASUAL: "Internet's acting up. Check your connection?", | |
MessageTone.EMPATHETIC: "Connection problems can be annoying. Let's get you back online." | |
}, | |
'pet_lifecycle_error': { | |
MessageTone.FRIENDLY: "Something went wrong with your DigiPal's growth. Let's help them! π£", | |
MessageTone.PROFESSIONAL: "Pet lifecycle error occurred. Data integrity may be compromised.", | |
MessageTone.CASUAL: "Your DigiPal hit a snag. Let's fix them up!", | |
MessageTone.EMPATHETIC: "We understand your DigiPal means a lot to you. Let's restore them safely." | |
}, | |
'system_error': { | |
MessageTone.FRIENDLY: "Something unexpected happened, but we're on it! π§", | |
MessageTone.PROFESSIONAL: "A system error occurred. Please try restarting the application.", | |
MessageTone.CASUAL: "Things got weird. Maybe restart?", | |
MessageTone.EMPATHETIC: "Technical issues can be frustrating. We're here to help you through this." | |
} | |
} | |
def _initialize_recovery_guides(self) -> Dict[str, List[Dict[str, Any]]]: | |
"""Initialize step-by-step recovery guides.""" | |
return { | |
'authentication': [ | |
{ | |
'step': 1, | |
'title': 'Check Your Credentials', | |
'description': 'Make sure your HuggingFace username and token are correct', | |
'action': 'verify_credentials', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 2, | |
'title': 'Test Your Connection', | |
'description': 'Ensure you have a stable internet connection', | |
'action': 'test_connection', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 3, | |
'title': 'Try Offline Mode', | |
'description': 'Use the application in offline mode with limited features', | |
'action': 'enable_offline_mode', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 4, | |
'title': 'Clear Browser Data', | |
'description': 'Clear cookies and cached data, then try logging in again', | |
'action': 'clear_browser_data', | |
'difficulty': 'medium' | |
} | |
], | |
'storage': [ | |
{ | |
'step': 1, | |
'title': 'Check Disk Space', | |
'description': 'Make sure you have at least 100MB of free disk space', | |
'action': 'check_disk_space', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 2, | |
'title': 'Restart Application', | |
'description': 'Close and reopen DigiPal to reset the storage connection', | |
'action': 'restart_application', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 3, | |
'title': 'Restore from Backup', | |
'description': 'Use an automatic backup to restore your DigiPal data', | |
'action': 'restore_backup', | |
'difficulty': 'medium' | |
}, | |
{ | |
'step': 4, | |
'title': 'Check File Permissions', | |
'description': 'Ensure DigiPal has permission to write to its data directory', | |
'action': 'check_permissions', | |
'difficulty': 'hard' | |
} | |
], | |
'ai_model': [ | |
{ | |
'step': 1, | |
'title': 'Wait and Retry', | |
'description': 'AI services may be temporarily busy. Wait 30 seconds and try again', | |
'action': 'wait_and_retry', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 2, | |
'title': 'Use Simple Commands', | |
'description': 'Try using shorter, simpler phrases when talking to your DigiPal', | |
'action': 'use_simple_commands', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 3, | |
'title': 'Switch to Text Mode', | |
'description': 'Use text input instead of speech if available', | |
'action': 'switch_to_text', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 4, | |
'title': 'Restart Application', | |
'description': 'Close and reopen DigiPal to reload the AI models', | |
'action': 'restart_application', | |
'difficulty': 'medium' | |
} | |
], | |
'speech_processing': [ | |
{ | |
'step': 1, | |
'title': 'Check Microphone', | |
'description': 'Make sure your microphone is connected and working', | |
'action': 'check_microphone', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 2, | |
'title': 'Reduce Background Noise', | |
'description': 'Find a quieter location or reduce background noise', | |
'action': 'reduce_noise', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 3, | |
'title': 'Speak Clearly', | |
'description': 'Speak slowly and clearly, facing the microphone', | |
'action': 'speak_clearly', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 4, | |
'title': 'Use Text Input', | |
'description': 'Switch to typing your messages instead of speaking', | |
'action': 'use_text_input', | |
'difficulty': 'easy' | |
} | |
], | |
'network': [ | |
{ | |
'step': 1, | |
'title': 'Check Internet Connection', | |
'description': 'Make sure you\'re connected to the internet', | |
'action': 'check_internet', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 2, | |
'title': 'Try Different Network', | |
'description': 'Switch to a different WiFi network or use mobile data', | |
'action': 'switch_network', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 3, | |
'title': 'Use Offline Mode', | |
'description': 'Continue using DigiPal with cached data and limited features', | |
'action': 'enable_offline_mode', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 4, | |
'title': 'Check Firewall Settings', | |
'description': 'Ensure DigiPal is allowed through your firewall', | |
'action': 'check_firewall', | |
'difficulty': 'hard' | |
} | |
], | |
'pet_lifecycle': [ | |
{ | |
'step': 1, | |
'title': 'Reload Your DigiPal', | |
'description': 'Try refreshing the page or restarting the application', | |
'action': 'reload_pet', | |
'difficulty': 'easy' | |
}, | |
{ | |
'step': 2, | |
'title': 'Check Recent Backups', | |
'description': 'Look for recent automatic backups of your DigiPal', | |
'action': 'check_backups', | |
'difficulty': 'medium' | |
}, | |
{ | |
'step': 3, | |
'title': 'Restore from Backup', | |
'description': 'Restore your DigiPal from the most recent backup', | |
'action': 'restore_from_backup', | |
'difficulty': 'medium' | |
}, | |
{ | |
'step': 4, | |
'title': 'Contact Support', | |
'description': 'If all else fails, contact support for manual data recovery', | |
'action': 'contact_support', | |
'difficulty': 'easy' | |
} | |
] | |
} | |
def _initialize_contextual_messages(self) -> Dict[str, Dict[str, str]]: | |
"""Initialize contextual messages based on user state.""" | |
return { | |
'first_time_user': { | |
'authentication': "Welcome to DigiPal! Let's get you set up with your HuggingFace account.", | |
'storage': "We're setting up your DigiPal's home. This might take a moment.", | |
'ai_model': "Your DigiPal is learning to talk! This may take a few minutes on first startup." | |
}, | |
'returning_user': { | |
'authentication': "Welcome back! Let's get you reconnected to your DigiPal.", | |
'storage': "Loading your DigiPal's data. They've missed you!", | |
'ai_model': "Your DigiPal is waking up and getting ready to chat!" | |
}, | |
'during_evolution': { | |
'pet_lifecycle': "Your DigiPal is in the middle of evolving! Let's make sure this goes smoothly.", | |
'storage': "We're saving your DigiPal's evolution progress. This is important!" | |
}, | |
'during_interaction': { | |
'speech_processing': "Your DigiPal is listening carefully. Let's make sure they can hear you clearly.", | |
'ai_model': "Your DigiPal is thinking about what to say. Sometimes they need a moment!" | |
} | |
} | |
def generate_user_message( | |
self, | |
error: DigiPalException, | |
tone: Optional[MessageTone] = None, | |
user_context: Optional[Dict[str, Any]] = None | |
) -> str: | |
""" | |
Generate a user-friendly error message. | |
Args: | |
error: The error that occurred | |
tone: Message tone to use | |
user_context: Additional user context | |
Returns: | |
User-friendly error message | |
""" | |
tone = tone or self.default_tone | |
user_context = user_context or {} | |
# Get base message template | |
error_type = self._get_error_type_key(error) | |
base_message = self.message_templates.get(error_type, {}).get( | |
tone, | |
"Something unexpected happened, but we're working on it!" | |
) | |
# Add contextual information | |
contextual_key = user_context.get('user_state', 'general') | |
if contextual_key in self.contextual_messages: | |
contextual_msg = self.contextual_messages[contextual_key].get(error.category.value) | |
if contextual_msg: | |
base_message = f"{contextual_msg} {base_message}" | |
# Add severity-specific information | |
if error.severity == ErrorSeverity.CRITICAL: | |
base_message += " This is a critical issue that needs immediate attention." | |
elif error.severity == ErrorSeverity.HIGH: | |
base_message += " This is important to fix to ensure your DigiPal works properly." | |
return base_message | |
def get_recovery_guide( | |
self, | |
error: DigiPalException, | |
max_steps: int = 4, | |
difficulty_filter: Optional[str] = None | |
) -> List[Dict[str, Any]]: | |
""" | |
Get step-by-step recovery guide for an error. | |
Args: | |
error: The error that occurred | |
max_steps: Maximum number of steps to return | |
difficulty_filter: Filter by difficulty ('easy', 'medium', 'hard') | |
Returns: | |
List of recovery steps | |
""" | |
category_key = error.category.value | |
guide_steps = self.recovery_guides.get(category_key, []) | |
# Filter by difficulty if specified | |
if difficulty_filter: | |
guide_steps = [step for step in guide_steps if step['difficulty'] == difficulty_filter] | |
# Limit number of steps | |
guide_steps = guide_steps[:max_steps] | |
# Add error-specific context to steps | |
for step in guide_steps: | |
step['error_code'] = error.error_code | |
step['error_category'] = error.category.value | |
# Add specific instructions based on error context | |
if error.context: | |
step['context'] = error.context | |
return guide_steps | |
def _get_error_type_key(self, error: DigiPalException) -> str: | |
"""Get the error type key for message templates.""" | |
category_mapping = { | |
ErrorCategory.AUTHENTICATION: 'authentication_failed', | |
ErrorCategory.STORAGE: 'storage_error', | |
ErrorCategory.AI_MODEL: 'ai_model_error', | |
ErrorCategory.SPEECH_PROCESSING: 'speech_processing_error', | |
ErrorCategory.IMAGE_GENERATION: 'image_generation_error', | |
ErrorCategory.NETWORK: 'network_error', | |
ErrorCategory.PET_LIFECYCLE: 'pet_lifecycle_error', | |
ErrorCategory.SYSTEM: 'system_error' | |
} | |
return category_mapping.get(error.category, 'system_error') | |
def generate_progress_message(self, recovery_step: Dict[str, Any]) -> str: | |
""" | |
Generate a progress message for a recovery step. | |
Args: | |
recovery_step: Recovery step information | |
Returns: | |
Progress message | |
""" | |
step_num = recovery_step.get('step', 1) | |
title = recovery_step.get('title', 'Recovery Step') | |
progress_messages = [ | |
f"Step {step_num}: {title}", | |
f"Working on: {title}", | |
f"Now trying: {title}", | |
f"Attempting: {title}" | |
] | |
# Choose message based on step number | |
message_index = (step_num - 1) % len(progress_messages) | |
return progress_messages[message_index] | |
def generate_success_message(self, error_category: str, recovery_method: str) -> str: | |
""" | |
Generate a success message after recovery. | |
Args: | |
error_category: Category of error that was recovered | |
recovery_method: Method used for recovery | |
Returns: | |
Success message | |
""" | |
success_messages = { | |
'authentication': "Great! You're logged in and ready to go! π", | |
'storage': "Perfect! Your DigiPal's data is safe and sound! πΎ", | |
'ai_model': "Awesome! Your DigiPal is ready to chat again! π€", | |
'speech_processing': "Excellent! Your DigiPal can hear you clearly now! π€", | |
'network': "Wonderful! You're back online! π", | |
'pet_lifecycle': "Amazing! Your DigiPal is healthy and happy! π£" | |
} | |
base_message = success_messages.get(error_category, "Great! The issue has been resolved! β ") | |
if recovery_method: | |
base_message += f" (Fixed using: {recovery_method})" | |
return base_message | |
# Global message generator instance | |
user_message_generator = UserErrorMessageGenerator() | |
def get_user_friendly_error_message( | |
error: DigiPalException, | |
tone: Optional[MessageTone] = None, | |
user_context: Optional[Dict[str, Any]] = None | |
) -> str: | |
""" | |
Get a user-friendly error message. | |
Args: | |
error: The error that occurred | |
tone: Message tone to use | |
user_context: Additional user context | |
Returns: | |
User-friendly error message | |
""" | |
return user_message_generator.generate_user_message(error, tone, user_context) | |
def get_recovery_guide( | |
error: DigiPalException, | |
max_steps: int = 4, | |
difficulty_filter: Optional[str] = None | |
) -> List[Dict[str, Any]]: | |
""" | |
Get recovery guide for an error. | |
Args: | |
error: The error that occurred | |
max_steps: Maximum number of steps | |
difficulty_filter: Filter by difficulty | |
Returns: | |
List of recovery steps | |
""" | |
return user_message_generator.get_recovery_guide(error, max_steps, difficulty_filter) |