From 88ba0a76abc133a0c15aa5eba13fac42b4b0b131 Mon Sep 17 00:00:00 2001 From: Lucas 'Paperboy' Rose-Winters Date: Wed, 22 Oct 2025 09:50:59 +1100 Subject: [PATCH] fix: add comprehensive error handling to Present Characters HTML building MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PROBLEM (from Salixfire's debug logs): - Parser successfully extracted 5 characters - Log showed complete characters array - Log stopped abruptly before "✓ HTML rendered to container" - This indicates exception thrown during HTML building (lines 217-281) DIAGNOSIS: - Parsing works perfectly (5 characters extracted) - Code crashes somewhere in the HTML building loop - User sees placeholder because exception prevents HTML from rendering - No error logs because crash happens silently LIKELY CAUSES: - getGroupMembers() throwing exception - Character avatar lookup failing - getSafeThumbnailUrl() failing - Missing null checks SOLUTION: Added comprehensive error handling and debug logging: 1. Added logging before HTML building starts - "Starting HTML generation for N characters" - This confirms code reaches HTML building phase 2. Wrapped each character in try-catch - Logs each character being processed: "Building HTML for character 1/5: Lady Julia" - Prevents one character error from crashing entire function - Code continues with other characters even if one fails 3. Added detailed avatar lookup logging: - "Looking up avatar for: {name}" - "In group chat, checking group members..." - "Group members count: N" - "Found avatar in group members/all characters/current character" - Shows final avatar URL (first 50 chars) 4. Wrapped getGroupMembers() in try-catch - Catches group-specific errors - Logs error but continues with regular character lookup 5. Added success/error logging for each character: - "✓ Successfully built HTML for {name}" - "✗ ERROR building HTML for {name}: {error.message}" - Logs full error stack for debugging 6. Added completion log: - "Finished building all character cards" - Confirms loop completed successfully EXPECTED OUTCOME: Next debug log from Salixfire will show EXACTLY: - Which character is causing the crash (if any) - What operation is failing (avatar lookup, HTML building, etc.) - Full error message and stack trace - Whether code completes or crashes This will allow us to identify and fix the root cause. Files changed: - src/systems/rendering/thoughts.js: Added try-catch blocks and comprehensive logging --- src/systems/rendering/thoughts.js | 133 +++++++++++++++++++----------- 1 file changed, 86 insertions(+), 47 deletions(-) diff --git a/src/systems/rendering/thoughts.js b/src/systems/rendering/thoughts.js index af42aa6..3d59c26 100644 --- a/src/systems/rendering/thoughts.js +++ b/src/systems/rendering/thoughts.js @@ -177,6 +177,9 @@ export function renderThoughts() { // Build HTML let html = ''; + debugLog('[RPG Thoughts] ==================== BUILDING HTML ===================='); + debugLog('[RPG Thoughts] Starting HTML generation for', presentCharacters.length + ' characters'); + // If no characters parsed, show a placeholder editable card if (presentCharacters.length === 0) { debugLog('[RPG Thoughts] ⚠ No characters parsed - showing placeholder card'); @@ -214,70 +217,106 @@ export function renderThoughts() { html += ''; } else { html += '
'; + + let characterIndex = 0; for (const char of presentCharacters) { - // Find character portrait - // Use a base64-encoded SVG placeholder as fallback to avoid 400 errors - let characterPortrait = FALLBACK_AVATAR_DATA_URI; + characterIndex++; - // console.log('[RPG Companion] Looking for avatar for:', char.name); + try { + debugLog(`[RPG Thoughts] Building HTML for character ${characterIndex}/${presentCharacters.length}:`, char.name); - // For group chats, search through group members first - if (selected_group) { - const groupMembers = getGroupMembers(selected_group); - const matchingMember = groupMembers.find(member => - member && member.name && namesMatch(member.name, char.name) - ); + // Find character portrait + // Use a base64-encoded SVG placeholder as fallback to avoid 400 errors + let characterPortrait = FALLBACK_AVATAR_DATA_URI; - if (matchingMember && matchingMember.avatar && matchingMember.avatar !== 'none') { - const thumbnailUrl = getSafeThumbnailUrl('avatar', matchingMember.avatar); - if (thumbnailUrl) { - characterPortrait = thumbnailUrl; + debugLog(`[RPG Thoughts] Looking up avatar for: ${char.name}`); + + // For group chats, search through group members first + if (selected_group) { + debugLog('[RPG Thoughts] In group chat, checking group members...'); + + try { + const groupMembers = getGroupMembers(selected_group); + debugLog('[RPG Thoughts] Group members count:', groupMembers ? groupMembers.length : 0); + + if (groupMembers && groupMembers.length > 0) { + const matchingMember = groupMembers.find(member => + member && member.name && namesMatch(member.name, char.name) + ); + + if (matchingMember && matchingMember.avatar && matchingMember.avatar !== 'none') { + const thumbnailUrl = getSafeThumbnailUrl('avatar', matchingMember.avatar); + if (thumbnailUrl) { + characterPortrait = thumbnailUrl; + debugLog('[RPG Thoughts] Found avatar in group members'); + } + } + } + } catch (groupError) { + debugLog('[RPG Thoughts] Error checking group members:', groupError.message); } } - } - // For regular chats or if not found in group, search all characters - if (characterPortrait === FALLBACK_AVATAR_DATA_URI && characters && characters.length > 0) { - const matchingCharacter = characters.find(c => - c && c.name && namesMatch(c.name, char.name) - ); + // For regular chats or if not found in group, search all characters + if (characterPortrait === FALLBACK_AVATAR_DATA_URI && characters && characters.length > 0) { + debugLog('[RPG Thoughts] Searching all characters...'); - if (matchingCharacter && matchingCharacter.avatar && matchingCharacter.avatar !== 'none') { - const thumbnailUrl = getSafeThumbnailUrl('avatar', matchingCharacter.avatar); - if (thumbnailUrl) { - characterPortrait = thumbnailUrl; + const matchingCharacter = characters.find(c => + c && c.name && namesMatch(c.name, char.name) + ); + + if (matchingCharacter && matchingCharacter.avatar && matchingCharacter.avatar !== 'none') { + const thumbnailUrl = getSafeThumbnailUrl('avatar', matchingCharacter.avatar); + if (thumbnailUrl) { + characterPortrait = thumbnailUrl; + debugLog('[RPG Thoughts] Found avatar in all characters'); + } } } - } - // If this is the current character in a 1-on-1 chat, use their portrait - if (this_chid !== undefined && characters[this_chid] && - characters[this_chid].name && namesMatch(characters[this_chid].name, char.name)) { - const thumbnailUrl = getSafeThumbnailUrl('avatar', characters[this_chid].avatar); - if (thumbnailUrl) { - characterPortrait = thumbnailUrl; + // If this is the current character in a 1-on-1 chat, use their portrait + if (this_chid !== undefined && characters[this_chid] && + characters[this_chid].name && namesMatch(characters[this_chid].name, char.name)) { + const thumbnailUrl = getSafeThumbnailUrl('avatar', characters[this_chid].avatar); + if (thumbnailUrl) { + characterPortrait = thumbnailUrl; + debugLog('[RPG Thoughts] Found avatar from current character'); + } } - } - // Get relationship emoji - const relationshipEmoji = relationshipEmojis[char.relationship] || '⚖️'; + debugLog(`[RPG Thoughts] Final avatar for ${char.name}:`, characterPortrait.substring(0, 50) + '...'); - html += ` -
-
- ${char.name} -
${relationshipEmoji}
-
-
-
- ${char.emoji} - ${char.name} + // Get relationship emoji + const relationshipEmoji = relationshipEmojis[char.relationship] || '⚖️'; + + debugLog(`[RPG Thoughts] Building HTML card for ${char.name}...`); + + html += ` +
+
+ ${char.name} +
${relationshipEmoji}
+
+
+
+ ${char.emoji} + ${char.name} +
+
${char.traits}
-
${char.traits}
-
- `; + `; + + debugLog(`[RPG Thoughts] ✓ Successfully built HTML for ${char.name}`); + + } catch (charError) { + debugLog(`[RPG Thoughts] ✗ ERROR building HTML for ${char.name}:`, charError.message); + debugLog('[RPG Thoughts] Error stack:', charError.stack); + // Continue with next character instead of crashing + } } + + debugLog('[RPG Thoughts] Finished building all character cards'); html += '
'; }