"feat: Implement UNICODE encoding fix for database operations"
This commit is contained in:
parent
fd9e51b291
commit
cdf7a27f23
1
backend/app/UNICODE_ENCODING_FIX.md
Normal file
1
backend/app/UNICODE_ENCODING_FIX.md
Normal file
@ -0,0 +1 @@
|
||||
|
Binary file not shown.
Binary file not shown.
1
backend/app/test_unicode_fix.py
Normal file
1
backend/app/test_unicode_fix.py
Normal file
@ -0,0 +1 @@
|
||||
|
@ -82,10 +82,20 @@ EMOJI_FALLBACK = {
|
||||
def safe_emoji(emoji: str) -> str:
|
||||
"""Gibt ein Emoji zurück oder einen ASCII-Fallback bei Encoding-Problemen."""
|
||||
try:
|
||||
# Teste, ob das Emoji dargestellt werden kann
|
||||
emoji.encode(sys.stdout.encoding or 'utf-8')
|
||||
# Erste Priorität: Teste, ob das Emoji dargestellt werden kann
|
||||
test_encoding = sys.stdout.encoding or 'utf-8'
|
||||
emoji.encode(test_encoding)
|
||||
|
||||
# Zweite Prüfung: Windows-spezifische cp1252-Codierung
|
||||
if os.name == 'nt':
|
||||
try:
|
||||
emoji.encode('cp1252')
|
||||
except UnicodeEncodeError:
|
||||
# Wenn cp1252 fehlschlägt, verwende Fallback
|
||||
return EMOJI_FALLBACK.get(emoji, '[?]')
|
||||
|
||||
return emoji
|
||||
except (UnicodeEncodeError, LookupError):
|
||||
except (UnicodeEncodeError, LookupError, AttributeError):
|
||||
return EMOJI_FALLBACK.get(emoji, '[?]')
|
||||
|
||||
# Prüfen, ob das Terminal ANSI-Farben unterstützt
|
||||
@ -135,39 +145,61 @@ class ColoredFormatter(logging.Formatter):
|
||||
}
|
||||
|
||||
def format(self, record):
|
||||
# Basis-Format erstellen
|
||||
log_fmt = LOG_FORMAT
|
||||
date_fmt = LOG_DATE_FORMAT
|
||||
try:
|
||||
# Basis-Format erstellen
|
||||
log_fmt = LOG_FORMAT
|
||||
date_fmt = LOG_DATE_FORMAT
|
||||
|
||||
# Emoji dem Level und der Kategorie hinzufügen
|
||||
level_name = record.levelname
|
||||
category_name = record.name.split('.')[-1] if '.' in record.name else record.name
|
||||
# Emoji dem Level und der Kategorie hinzufügen
|
||||
level_name = record.levelname
|
||||
category_name = record.name.split('.')[-1] if '.' in record.name else record.name
|
||||
|
||||
level_emoji = safe_emoji(LOG_EMOJIS.get(level_name, ''))
|
||||
category_emoji = safe_emoji(LOG_EMOJIS.get(category_name, ''))
|
||||
level_emoji = safe_emoji(LOG_EMOJIS.get(level_name, ''))
|
||||
category_emoji = safe_emoji(LOG_EMOJIS.get(category_name, ''))
|
||||
|
||||
# Record-Objekt modifizieren (aber temporär)
|
||||
original_levelname = record.levelname
|
||||
original_name = record.name
|
||||
# Record-Objekt modifizieren (aber temporär)
|
||||
original_levelname = record.levelname
|
||||
original_name = record.name
|
||||
|
||||
# Emojis hinzufügen
|
||||
record.levelname = f"{level_emoji} {level_name}"
|
||||
record.name = f"{category_emoji} {category_name}"
|
||||
# Emojis hinzufügen
|
||||
record.levelname = f"{level_emoji} {level_name}"
|
||||
record.name = f"{category_emoji} {category_name}"
|
||||
|
||||
# Farbe hinzufügen wenn unterstützt
|
||||
if USE_COLORS:
|
||||
level_color = self.level_colors.get(original_levelname, ANSI_COLORS['RESET'])
|
||||
record.levelname = f"{level_color}{record.levelname}{ANSI_COLORS['RESET']}"
|
||||
record.name = f"{ANSI_COLORS['BOLD']}{record.name}{ANSI_COLORS['RESET']}"
|
||||
# Farbe hinzufügen wenn unterstützt
|
||||
if USE_COLORS:
|
||||
level_color = self.level_colors.get(original_levelname, ANSI_COLORS['RESET'])
|
||||
record.levelname = f"{level_color}{record.levelname}{ANSI_COLORS['RESET']}"
|
||||
record.name = f"{ANSI_COLORS['BOLD']}{record.name}{ANSI_COLORS['RESET']}"
|
||||
|
||||
# Formatieren
|
||||
result = super().format(record)
|
||||
# Formatieren
|
||||
result = super().format(record)
|
||||
|
||||
# Originale Werte wiederherstellen
|
||||
record.levelname = original_levelname
|
||||
record.name = original_name
|
||||
# Originale Werte wiederherstellen
|
||||
record.levelname = original_levelname
|
||||
record.name = original_name
|
||||
|
||||
return result
|
||||
return result
|
||||
except (UnicodeEncodeError, UnicodeDecodeError, AttributeError) as e:
|
||||
# Fallback bei Unicode-Problemen: Verwende nur ASCII-Text
|
||||
original_levelname = record.levelname
|
||||
original_name = record.name
|
||||
|
||||
# Emojis durch ASCII-Fallbacks ersetzen
|
||||
level_fallback = EMOJI_FALLBACK.get(LOG_EMOJIS.get(original_levelname, ''), '[LOG]')
|
||||
category_name = record.name.split('.')[-1] if '.' in record.name else record.name
|
||||
category_fallback = EMOJI_FALLBACK.get(LOG_EMOJIS.get(category_name, ''), '[CAT]')
|
||||
|
||||
record.levelname = f"{level_fallback} {original_levelname}"
|
||||
record.name = f"{category_fallback} {category_name}"
|
||||
|
||||
# Basis-Formatierung ohne Farben
|
||||
result = super().format(record)
|
||||
|
||||
# Originale Werte wiederherstellen
|
||||
record.levelname = original_levelname
|
||||
record.name = original_name
|
||||
|
||||
return result
|
||||
|
||||
class DebugInfoFilter(logging.Filter):
|
||||
"""Filter, der Debug-Informationen zu jedem Log-Eintrag hinzufügt."""
|
||||
@ -228,12 +260,20 @@ def setup_logging(debug_mode: bool = False):
|
||||
console_handler.setLevel(log_level)
|
||||
console_handler.setFormatter(colored_formatter)
|
||||
console_handler.addFilter(debug_filter)
|
||||
|
||||
# Windows PowerShell UTF-8 Encoding-Unterstützung
|
||||
if os.name == 'nt' and hasattr(console_handler.stream, 'reconfigure'):
|
||||
try:
|
||||
console_handler.stream.reconfigure(encoding='utf-8')
|
||||
except:
|
||||
pass
|
||||
|
||||
root_logger.addHandler(console_handler)
|
||||
|
||||
# File Handler für allgemeine App-Logs
|
||||
app_log_file = get_log_file("app")
|
||||
app_handler = logging.handlers.RotatingFileHandler(
|
||||
app_log_file, maxBytes=10*1024*1024, backupCount=5
|
||||
app_log_file, maxBytes=10*1024*1024, backupCount=5, encoding='utf-8'
|
||||
)
|
||||
app_handler.setLevel(log_level)
|
||||
app_handler.setFormatter(file_formatter)
|
||||
@ -276,12 +316,20 @@ def get_logger(category: str) -> logging.Logger:
|
||||
console_handler.setLevel(getattr(logging, LOG_LEVEL))
|
||||
console_handler.setFormatter(colored_formatter)
|
||||
console_handler.addFilter(debug_filter)
|
||||
|
||||
# Windows PowerShell UTF-8 Encoding-Unterstützung
|
||||
if os.name == 'nt' and hasattr(console_handler.stream, 'reconfigure'):
|
||||
try:
|
||||
console_handler.stream.reconfigure(encoding='utf-8')
|
||||
except:
|
||||
pass
|
||||
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# File Handler für spezifische Kategorie
|
||||
log_file = get_log_file(category)
|
||||
file_handler = logging.handlers.RotatingFileHandler(
|
||||
log_file, maxBytes=10*1024*1024, backupCount=5
|
||||
log_file, maxBytes=10*1024*1024, backupCount=5, encoding='utf-8'
|
||||
)
|
||||
file_handler.setLevel(getattr(logging, LOG_LEVEL))
|
||||
file_handler.setFormatter(file_formatter)
|
||||
@ -291,7 +339,7 @@ def get_logger(category: str) -> logging.Logger:
|
||||
if category != "errors":
|
||||
error_log_file = get_log_file("errors")
|
||||
error_handler = logging.handlers.RotatingFileHandler(
|
||||
error_log_file, maxBytes=10*1024*1024, backupCount=5
|
||||
error_log_file, maxBytes=10*1024*1024, backupCount=5, encoding='utf-8'
|
||||
)
|
||||
error_handler.setLevel(logging.ERROR)
|
||||
error_handler.setFormatter(file_formatter)
|
||||
|
Loading…
x
Reference in New Issue
Block a user