Better error logs when reporting bug/uploading chat session (#370)

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
This commit is contained in:
Will Chen
2025-06-09 14:56:22 -07:00
committed by GitHub
parent 8d9962ddfc
commit c2696cf1f9
3 changed files with 51 additions and 10 deletions

View File

@@ -83,10 +83,11 @@ export function HelpDialog({ isOpen, onClose }: HelpDialogProps) {
- Dyad Version: ${debugInfo.dyadVersion} - Dyad Version: ${debugInfo.dyadVersion}
- Platform: ${debugInfo.platform} - Platform: ${debugInfo.platform}
- Architecture: ${debugInfo.architecture} - Architecture: ${debugInfo.architecture}
- Node Version: ${debugInfo.nodeVersion || "Not available"} - Node Version: ${debugInfo.nodeVersion || "n/a"}
- PNPM Version: ${debugInfo.pnpmVersion || "Not available"} - PNPM Version: ${debugInfo.pnpmVersion || "n/a"}
- Node Path: ${debugInfo.nodePath || "Not available"} - Node Path: ${debugInfo.nodePath || "n/a"}
- Telemetry ID: ${debugInfo.telemetryId || "Not available"} - Telemetry ID: ${debugInfo.telemetryId || "n/a"}
- Model: ${debugInfo.selectedLanguageModel || "n/a"}
## Logs ## Logs
\`\`\` \`\`\`

View File

@@ -12,9 +12,16 @@ import { db } from "../../db";
import { chats, apps } from "../../db/schema"; import { chats, apps } from "../../db/schema";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { getDyadAppPath } from "../../paths/paths"; import { getDyadAppPath } from "../../paths/paths";
import { LargeLanguageModel } from "@/lib/schemas";
// Shared function to get system debug info // Shared function to get system debug info
async function getSystemDebugInfo(): Promise<SystemDebugInfo> { async function getSystemDebugInfo({
linesOfLogs,
level,
}: {
linesOfLogs: number;
level: "warn" | "info";
}): Promise<SystemDebugInfo> {
console.log("Getting system debug info"); console.log("Getting system debug info");
// Get Node.js and pnpm versions // Get Node.js and pnpm versions
@@ -63,8 +70,27 @@ async function getSystemDebugInfo(): Promise<SystemDebugInfo> {
const logPath = log.transports.file.getFile().path; const logPath = log.transports.file.getFile().path;
if (fs.existsSync(logPath)) { if (fs.existsSync(logPath)) {
const logContent = fs.readFileSync(logPath, "utf8"); const logContent = fs.readFileSync(logPath, "utf8");
const logLines = logContent.split("\n");
logs = logLines.slice(-100).join("\n"); const logLines = logContent.split("\n").filter((line) => {
if (level === "info") {
return true;
}
// Example line:
// [2025-06-09 13:55:05.209] [debug] (runShellCommand) Command "which node" succeeded with code 0: /usr/local/bin/node
const logLevelRegex = /\[.*?\] \[(\w+)\]/;
const match = line.match(logLevelRegex);
if (!match) {
// Include non-matching lines (like stack traces) when filtering for warnings
return true;
}
const logLevel = match[1];
if (level === "warn") {
return logLevel === "warn" || logLevel === "error";
}
return true;
});
logs = logLines.slice(-linesOfLogs).join("\n");
} }
} catch (err) { } catch (err) {
console.error("Failed to read log file:", err); console.error("Failed to read log file:", err);
@@ -76,6 +102,8 @@ async function getSystemDebugInfo(): Promise<SystemDebugInfo> {
pnpmVersion, pnpmVersion,
nodePath, nodePath,
telemetryId, telemetryId,
selectedLanguageModel:
serializeModelForDebug(settings.selectedModel) || "unknown",
telemetryConsent: settings.telemetryConsent || "unknown", telemetryConsent: settings.telemetryConsent || "unknown",
telemetryUrl: "https://us.i.posthog.com", // Hardcoded from renderer.tsx telemetryUrl: "https://us.i.posthog.com", // Hardcoded from renderer.tsx
dyadVersion, dyadVersion,
@@ -90,7 +118,10 @@ export function registerDebugHandlers() {
"get-system-debug-info", "get-system-debug-info",
async (): Promise<SystemDebugInfo> => { async (): Promise<SystemDebugInfo> => {
console.log("IPC: get-system-debug-info called"); console.log("IPC: get-system-debug-info called");
return getSystemDebugInfo(); return getSystemDebugInfo({
linesOfLogs: 20,
level: "warn",
});
}, },
); );
@@ -100,8 +131,12 @@ export function registerDebugHandlers() {
console.log(`IPC: get-chat-logs called for chat ${chatId}`); console.log(`IPC: get-chat-logs called for chat ${chatId}`);
try { try {
// Get system debug info using the shared function // We can retrieve a lot more lines here because we're not limited by the
const debugInfo = await getSystemDebugInfo(); // GitHub issue URL length limit.
const debugInfo = await getSystemDebugInfo({
linesOfLogs: 1_000,
level: "info",
});
// Get chat data from database // Get chat data from database
const chatRecord = await db.query.chats.findFirst({ const chatRecord = await db.query.chats.findFirst({
@@ -156,3 +191,7 @@ export function registerDebugHandlers() {
console.log("Registered debug IPC handlers"); console.log("Registered debug IPC handlers");
} }
function serializeModelForDebug(model: LargeLanguageModel): string {
return `${model.provider}:${model.name} | customId: ${model.customModelId}`;
}

View File

@@ -104,6 +104,7 @@ export interface SystemDebugInfo {
platform: string; platform: string;
architecture: string; architecture: string;
logs: string; logs: string;
selectedLanguageModel: string;
} }
export interface LocalModel { export interface LocalModel {