|
import fs from 'fs/promises'; |
|
import path from 'path'; |
|
|
|
const DEBUG_DIR = 'debug'; |
|
|
|
|
|
async function ensureDebugDir() { |
|
try { |
|
await fs.access(DEBUG_DIR); |
|
} catch { |
|
await fs.mkdir(DEBUG_DIR, { recursive: true }); |
|
} |
|
} |
|
|
|
|
|
export async function saveScreenshot(debugId: string, screenshot: Buffer): Promise<void> { |
|
await ensureDebugDir(); |
|
const screenshotPath = path.join(DEBUG_DIR, `${debugId}.png`); |
|
await fs.writeFile(screenshotPath, screenshot); |
|
} |
|
|
|
|
|
export async function saveDebugInfo(debugId: string, info: any): Promise<void> { |
|
await ensureDebugDir(); |
|
const infoPath = path.join(DEBUG_DIR, `${debugId}.json`); |
|
await fs.writeFile(infoPath, JSON.stringify(info, null, 2)); |
|
} |
|
|
|
|
|
export async function saveErrorInfo(debugId: string, error: any): Promise<void> { |
|
await ensureDebugDir(); |
|
const errorPath = path.join(DEBUG_DIR, `${debugId}_error.json`); |
|
await fs.writeFile(errorPath, JSON.stringify(error, null, 2)); |
|
} |
|
|
|
|
|
export async function getAllDebugInfo(): Promise<any[]> { |
|
try { |
|
await ensureDebugDir(); |
|
const files = await fs.readdir(DEBUG_DIR); |
|
const debugItems = []; |
|
|
|
|
|
const infoFiles = files.filter(file => file.endsWith('.json') && !file.endsWith('_error.json')); |
|
|
|
for (const file of infoFiles) { |
|
try { |
|
const debugId = file.replace('.json', ''); |
|
const infoPath = path.join(DEBUG_DIR, file); |
|
const errorPath = path.join(DEBUG_DIR, `${debugId}_error.json`); |
|
const screenshotPath = path.join(DEBUG_DIR, `${debugId}.png`); |
|
|
|
|
|
const infoData = await fs.readFile(infoPath, 'utf-8'); |
|
const info = JSON.parse(infoData); |
|
|
|
|
|
let errorInfo = null; |
|
try { |
|
const errorData = await fs.readFile(errorPath, 'utf-8'); |
|
errorInfo = JSON.parse(errorData); |
|
} catch { |
|
|
|
} |
|
|
|
|
|
let hasScreenshot = false; |
|
try { |
|
await fs.access(screenshotPath); |
|
hasScreenshot = true; |
|
} catch { |
|
|
|
} |
|
|
|
debugItems.push({ |
|
debugId, |
|
...info, |
|
hasError: !!errorInfo, |
|
errorMessage: errorInfo?.error || null, |
|
hasScreenshot, |
|
screenshotUrl: hasScreenshot ? `/api/debug/screenshot?id=${debugId}` : null |
|
}); |
|
} catch (error) { |
|
console.error(`Error reading debug file ${file}:`, error); |
|
} |
|
} |
|
|
|
|
|
debugItems.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); |
|
|
|
return debugItems; |
|
} catch (error) { |
|
console.error('Error reading debug directory:', error); |
|
return []; |
|
} |
|
} |
|
|
|
|
|
export async function getScreenshot(debugId: string): Promise<Buffer | null> { |
|
try { |
|
const screenshotPath = path.join(DEBUG_DIR, `${debugId}.png`); |
|
return await fs.readFile(screenshotPath); |
|
} catch { |
|
return null; |
|
} |
|
} |
|
|
|
|
|
export async function cleanupOldDebugFiles(daysToKeep: number = 7): Promise<number> { |
|
try { |
|
await ensureDebugDir(); |
|
const files = await fs.readdir(DEBUG_DIR); |
|
const cutoffTime = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000); |
|
let deletedCount = 0; |
|
|
|
for (const file of files) { |
|
try { |
|
const filePath = path.join(DEBUG_DIR, file); |
|
const stats = await fs.stat(filePath); |
|
|
|
if (stats.mtime.getTime() < cutoffTime) { |
|
await fs.unlink(filePath); |
|
deletedCount++; |
|
} |
|
} catch (error) { |
|
console.error(`Error processing file ${file}:`, error); |
|
} |
|
} |
|
|
|
return deletedCount; |
|
} catch (error) { |
|
console.error('Error cleaning up debug files:', error); |
|
return 0; |
|
} |
|
} |
|
|