debug-parse18.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. const fs = require('fs');
  2. const content = fs.readFileSync('temp/rich-outline-fail_57_1779015509994.txt', 'utf-8');
  3. const marker = '========== AI 原始响应 ';
  4. const markerIdx = content.indexOf(marker);
  5. const headerEndIdx = content.indexOf(' ==========', markerIdx);
  6. const aiStart = content.indexOf('\n', headerEndIdx) + 1;
  7. const aiEnd = content.indexOf('\n\n', aiStart);
  8. const aiResponse = content.substring(aiStart, aiEnd);
  9. console.log('AI response length:', aiResponse.length);
  10. // Let me try a completely different approach: check if there's a smarter fix
  11. // I'll look for ALL occurrences of },{ followed by an unquoted property name
  12. // First, let's find what property names are used after },{
  13. const allCases = [];
  14. const regex = /\},\{([^"]+):/g;
  15. let match;
  16. while ((match = regex.exec(aiResponse)) !== null) {
  17. allCases.push({pos: match.index, prop: match[1]});
  18. }
  19. console.log('Found', allCases.length, 'cases of },{propName:');
  20. if (allCases.length < 20) {
  21. allCases.forEach(c => console.log(' pos', c.pos, ':', c.prop));
  22. }
  23. // Check if maybe there are nested issues
  24. // Let's try parsing from the beginning but stop at position 1624
  25. const truncatedAtError = aiResponse.substring(0, 1624) + '"}]}]}'; // Close all open structures
  26. try {
  27. JSON.parse(truncatedAtError);
  28. console.log('Truncated parse: SUCCESS');
  29. } catch(e) {
  30. console.log('Truncated parse: FAILED -', e.message.substring(0, 80));
  31. }
  32. // Try a different fix: replace ALL },{ with },{"
  33. const fixedV2 = aiResponse.replace(/\},\{([a-zA-Z_])/g, '},{"$1');
  34. try {
  35. const data = JSON.parse(fixedV2);
  36. console.log('\nFix v2: SUCCESS, chapters:', data.chapters?.length);
  37. } catch(e) {
  38. console.log('\nFix v2: FAILED -', e.message.substring(0, 80));
  39. // Find which occurrence is problematic
  40. const fixedPos = parseInt(e.message.match(/position (\d+)/)?.[1] || '0');
  41. console.log('Error at position', fixedPos);
  42. console.log('Context:', JSON.stringify(fixedV2.substring(Math.max(0, fixedPos-50), fixedPos+50)));
  43. }
  44. // Let's also check for a different issue - what if there's a missing comma between array elements?
  45. // Check for patterns like "keyPoints":["foo","bar"]}{"next"
  46. const badTransition = /\]\}\{/g;
  47. const badTransitions = aiResponse.match(badTransition);
  48. console.log('\nFound', badTransitions ? badTransitions.length : 0, 'instances of ]}{ (missing comma)');
  49. // Let's check if the entire JSON is actually truncated - look at the very end
  50. console.log('\n=== End of JSON ===');
  51. console.log('Last 200 chars:', JSON.stringify(aiResponse.substring(aiResponse.length - 200)));
  52. // Try parsing from start, but let's see if we can find any workaround
  53. // What if we just try to extract the chapters array without the outer structure?
  54. const chaptersMatch = aiResponse.match(/"chapters"\s*:\s*\[([\s\S]*)\]\s*\}$/);
  55. if (chaptersMatch) {
  56. console.log('\nFound chapters array match, length:', chaptersMatch[1].length);
  57. try {
  58. const chaptersStr = '[{"number":1' + chaptersMatch[1];
  59. const data = JSON.parse(chaptersStr);
  60. console.log('Chapters extraction: SUCCESS, count:', data.length);
  61. } catch(e) {
  62. console.log('Chapters extraction: FAILED -', e.message.substring(0, 80));
  63. }
  64. } else {
  65. console.log('\nNo chapters array found at expected location');
  66. }