Reduce remaining MCP and persistence debug detail

This commit is contained in:
2026-04-04 09:52:38 +08:00
parent 02f22d80bd
commit 010ded8476
4 changed files with 240 additions and 72 deletions

View File

@@ -377,6 +377,49 @@ function summarizeStderrForDebug(stderrOutput: string): string {
return `Server stderr captured (${trimmed.length} chars, ${lineCount} lines)`
}
function summarizeMcpErrorForDebug(error: unknown): string {
const summary: Record<string, boolean | number | string> = {}
if (error instanceof Error) {
summary.errorType = error.constructor.name
summary.errorName = error.name
summary.hasMessage = error.message.length > 0
summary.hasStack = Boolean(error.stack)
const errorObj = error as Error & {
code?: unknown
errno?: unknown
syscall?: unknown
status?: unknown
cause?: unknown
}
if (typeof errorObj.code === 'string' || typeof errorObj.code === 'number') {
summary.code = errorObj.code
}
if (
typeof errorObj.errno === 'string' ||
typeof errorObj.errno === 'number'
) {
summary.errno = errorObj.errno
}
if (typeof errorObj.syscall === 'string') {
summary.syscall = errorObj.syscall
}
if (typeof errorObj.status === 'number') {
summary.status = errorObj.status
}
if (errorObj.cause !== undefined) {
summary.hasCause = true
}
} else {
summary.errorType = typeof error
summary.hasValue = error !== undefined && error !== null
}
return jsonStringify(summary)
}
/**
* Shared handler for sse/http/claudeai-proxy auth failures during connect:
* emits tengu_mcp_server_needs_auth, caches the needs-auth entry, and returns
@@ -1077,20 +1120,22 @@ export const connectToServer = memoize(
)
try {
const testUrl = new URL(serverRef.url)
logMCPDebug(
name,
`Parsed URL: host=${testUrl.hostname}, port=${testUrl.port || 'default'}, protocol=${testUrl.protocol}`,
)
logMCPDebug(name, 'Parsed HTTP endpoint for preflight checks')
// Log DNS resolution attempt
if (
testUrl.hostname === '127.0.0.1' ||
testUrl.hostname === 'localhost'
) {
logMCPDebug(name, `Using loopback address: ${testUrl.hostname}`)
logMCPDebug(name, 'Using loopback HTTP endpoint')
}
} catch (urlError) {
logMCPDebug(name, `Failed to parse URL: ${urlError}`)
logMCPDebug(
name,
`Failed to parse HTTP endpoint for preflight: ${summarizeMcpErrorForDebug(
urlError,
)}`,
)
}
}
@@ -1142,30 +1187,29 @@ export const connectToServer = memoize(
if (serverRef.type === 'sse' && error instanceof Error) {
logMCPDebug(
name,
`SSE Connection failed after ${elapsed}ms: ${jsonStringify({
url: serverRef.url,
error: error.message,
errorType: error.constructor.name,
stack: error.stack,
})}`,
`SSE connection failed after ${elapsed}ms: ${summarizeMcpErrorForDebug(
error,
)}`,
)
logMCPError(
name,
`SSE connection failed: ${summarizeMcpErrorForDebug(error)}`,
)
logMCPError(name, error)
if (error instanceof UnauthorizedError) {
return handleRemoteAuthFailure(name, serverRef, 'sse')
}
} else if (serverRef.type === 'http' && error instanceof Error) {
const errorObj = error as Error & {
cause?: unknown
code?: string
errno?: string | number
syscall?: string
}
logMCPDebug(
name,
`HTTP Connection failed after ${elapsed}ms: ${error.message} (code: ${errorObj.code || 'none'}, errno: ${errorObj.errno || 'none'})`,
`HTTP connection failed after ${elapsed}ms: ${summarizeMcpErrorForDebug(
error,
)}`,
)
logMCPError(
name,
`HTTP connection failed: ${summarizeMcpErrorForDebug(error)}`,
)
logMCPError(name, error)
if (error instanceof UnauthorizedError) {
return handleRemoteAuthFailure(name, serverRef, 'http')
@@ -1176,9 +1220,16 @@ export const connectToServer = memoize(
) {
logMCPDebug(
name,
`claude.ai proxy connection failed after ${elapsed}ms: ${error.message}`,
`claude.ai proxy connection failed after ${elapsed}ms: ${summarizeMcpErrorForDebug(
error,
)}`,
)
logMCPError(
name,
`claude.ai proxy connection failed: ${summarizeMcpErrorForDebug(
error,
)}`,
)
logMCPError(name, error)
// StreamableHTTPError has a `code` property with the HTTP status
const errorCode = (error as Error & { code?: number }).code
@@ -1257,7 +1308,9 @@ export const connectToServer = memoize(
} catch (error) {
logMCPError(
name,
`Failed to send ide_connected notification: ${error}`,
`Failed to send ide_connected notification: ${summarizeMcpErrorForDebug(
error,
)}`,
)
}
}
@@ -1291,7 +1344,10 @@ export const connectToServer = memoize(
hasTriggeredClose = true
logMCPDebug(name, `Closing transport (${reason})`)
void client.close().catch(e => {
logMCPDebug(name, `Error during close: ${errorMessage(e)}`)
logMCPDebug(
name,
`Error during close: ${summarizeMcpErrorForDebug(e)}`,
)
})
}
@@ -1355,7 +1411,10 @@ export const connectToServer = memoize(
`Failed to spawn process - check command and permissions`,
)
} else {
logMCPDebug(name, `Connection error: ${error.message}`)
logMCPDebug(
name,
`Connection error: ${summarizeMcpErrorForDebug(error)}`,
)
}
}
@@ -1456,12 +1515,20 @@ export const connectToServer = memoize(
try {
await inProcessServer.close()
} catch (error) {
logMCPDebug(name, `Error closing in-process server: ${error}`)
logMCPDebug(
name,
`Error closing in-process server: ${summarizeMcpErrorForDebug(
error,
)}`,
)
}
try {
await client.close()
} catch (error) {
logMCPDebug(name, `Error closing client: ${error}`)
logMCPDebug(
name,
`Error closing client: ${summarizeMcpErrorForDebug(error)}`,
)
}
return
}
@@ -1487,7 +1554,10 @@ export const connectToServer = memoize(
try {
process.kill(childPid, 'SIGINT')
} catch (error) {
logMCPDebug(name, `Error sending SIGINT: ${error}`)
logMCPDebug(
name,
`Error sending SIGINT: ${summarizeMcpErrorForDebug(error)}`,
)
return
}
@@ -1541,7 +1611,12 @@ export const connectToServer = memoize(
try {
process.kill(childPid, 'SIGTERM')
} catch (termError) {
logMCPDebug(name, `Error sending SIGTERM: ${termError}`)
logMCPDebug(
name,
`Error sending SIGTERM: ${summarizeMcpErrorForDebug(
termError,
)}`,
)
resolved = true
clearInterval(checkInterval)
clearTimeout(failsafeTimeout)
@@ -1574,7 +1649,9 @@ export const connectToServer = memoize(
} catch (killError) {
logMCPDebug(
name,
`Error sending SIGKILL: ${killError}`,
`Error sending SIGKILL: ${summarizeMcpErrorForDebug(
killError,
)}`,
)
}
} catch {
@@ -1606,7 +1683,12 @@ export const connectToServer = memoize(
})
}
} catch (processError) {
logMCPDebug(name, `Error terminating process: ${processError}`)
logMCPDebug(
name,
`Error terminating process: ${summarizeMcpErrorForDebug(
processError,
)}`,
)
}
}
@@ -1614,7 +1696,10 @@ export const connectToServer = memoize(
try {
await client.close()
} catch (error) {
logMCPDebug(name, `Error closing client: ${error}`)
logMCPDebug(
name,
`Error closing client: ${summarizeMcpErrorForDebug(error)}`,
)
}
}
@@ -1671,9 +1756,14 @@ export const connectToServer = memoize(
})
logMCPDebug(
name,
`Connection failed after ${connectionDurationMs}ms: ${errorMessage(error)}`,
`Connection failed after ${connectionDurationMs}ms: ${summarizeMcpErrorForDebug(
error,
)}`,
)
logMCPError(
name,
`Connection failed: ${summarizeMcpErrorForDebug(error)}`,
)
logMCPError(name, `Connection failed: ${errorMessage(error)}`)
if (inProcessServer) {
inProcessServer.close().catch(() => {})
@@ -2038,7 +2128,10 @@ export const fetchToolsForClient = memoizeWithLRU(
})
.filter(isIncludedMcpTool)
} catch (error) {
logMCPError(client.name, `Failed to fetch tools: ${errorMessage(error)}`)
logMCPError(
client.name,
`Failed to fetch tools: ${summarizeMcpErrorForDebug(error)}`,
)
return []
}
},
@@ -2070,7 +2163,7 @@ export const fetchResourcesForClient = memoizeWithLRU(
} catch (error) {
logMCPError(
client.name,
`Failed to fetch resources: ${errorMessage(error)}`,
`Failed to fetch resources: ${summarizeMcpErrorForDebug(error)}`,
)
return []
}
@@ -2136,7 +2229,9 @@ export const fetchCommandsForClient = memoizeWithLRU(
} catch (error) {
logMCPError(
client.name,
`Error running command '${prompt.name}': ${errorMessage(error)}`,
`Error running command '${prompt.name}': ${summarizeMcpErrorForDebug(
error,
)}`,
)
throw error
}
@@ -2146,7 +2241,7 @@ export const fetchCommandsForClient = memoizeWithLRU(
} catch (error) {
logMCPError(
client.name,
`Failed to fetch commands: ${errorMessage(error)}`,
`Failed to fetch commands: ${summarizeMcpErrorForDebug(error)}`,
)
return []
}
@@ -2247,7 +2342,10 @@ export async function reconnectMcpServerImpl(
}
} catch (error) {
// Handle errors gracefully - connection might have closed during fetch
logMCPError(name, `Error during reconnection: ${errorMessage(error)}`)
logMCPError(
name,
`Error during reconnection: ${summarizeMcpErrorForDebug(error)}`,
)
// Return with failed status
return {
@@ -2422,7 +2520,9 @@ export async function getMcpToolsCommandsAndResources(
// Handle errors gracefully - connection might have closed during fetch
logMCPError(
name,
`Error fetching tools/commands/resources: ${errorMessage(error)}`,
`Error fetching tools/commands/resources: ${summarizeMcpErrorForDebug(
error,
)}`,
)
// Still update with the client but no tools/commands
@@ -2509,7 +2609,7 @@ export function prefetchAllMcpResources(
}, mcpConfigs).catch(error => {
logMCPError(
'prefetchAllMcpResources',
`Failed to get MCP resources: ${errorMessage(error)}`,
`Failed to get MCP resources: ${summarizeMcpErrorForDebug(error)}`,
)
// Still resolve with empty results
void resolve({
@@ -3371,7 +3471,12 @@ export async function setupSdkMcpClients(
}
} catch (error) {
// If connection fails, return failed server
logMCPError(name, `Failed to connect SDK MCP server: ${error}`)
logMCPError(
name,
`Failed to connect SDK MCP server: ${summarizeMcpErrorForDebug(
error,
)}`,
)
return {
client: {
type: 'failed' as const,