fix(core): log OpenAI error request IDs (#6379)

This commit is contained in:
tanzhenxin 2026-07-06 22:07:02 +08:00 committed by GitHub
parent 879b854e8a
commit 063535fc83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 74 additions and 6 deletions

View file

@ -344,6 +344,45 @@ describe('OpenAILogger', () => {
expect(logContent.response).toBeNull();
});
it('should log request id from OpenAI API errors', async () => {
const logger = new OpenAILogger(testTempDir);
await logger.initialize();
const error = Object.assign(new Error('Server error'), {
requestID: 'req-server-123',
});
const logPath = await logger.logInteraction(
{ model: 'gpt-4' },
undefined,
error,
);
const logContent = JSON.parse(await fs.readFile(logPath, 'utf-8'));
expect(logContent.error).toMatchObject({
message: 'Server error',
requestId: 'req-server-123',
});
});
it('should log request id from provider error payloads', async () => {
const logger = new OpenAILogger(testTempDir);
await logger.initialize();
const error = new Error(
'event:error\n:HTTP_STATUS/429\ndata:{"request_id":"req-provider-456","code":"Throttling.AllocationQuota","message":"Allocated quota exceeded"}',
);
const logPath = await logger.logInteraction(
{ model: 'qwen-plus' },
undefined,
error,
);
const logContent = JSON.parse(await fs.readFile(logPath, 'utf-8'));
expect(logContent.error.requestId).toBe('req-provider-456');
});
it('should use custom directory when provided', async () => {
const customDir = path.join(testTempDir, 'custom-logs');
const logger = new OpenAILogger(customDir);

View file

@ -10,6 +10,7 @@ import { v4 as uuidv4 } from 'uuid';
import * as os from 'os';
import { createDebugLogger } from './debugLogger.js';
import { isInternalPromptId } from './internalPromptIds.js';
import { getRateLimitErrorDetails } from './rateLimit.js';
const debugLogger = createDebugLogger('OPENAI_LOGGER');
const MAIN_SESSION_PROMPT_ID_DELIMITER = '########';
@ -111,6 +112,39 @@ function contextForPromptId(
};
}
function getString(value: unknown): string | undefined {
return typeof value === 'string' && value ? value : undefined;
}
function getErrorRequestId(error: Error): string | undefined {
const source = error as {
requestID?: unknown;
request_id?: unknown;
requestId?: unknown;
response_id?: unknown;
};
return (
getString(source.requestID) ??
getString(source.request_id) ??
getString(source.requestId) ??
getString(source.response_id) ??
getRateLimitErrorDetails(error).requestId
);
}
function serializeError(error: Error): {
message: string;
stack?: string;
requestId?: string;
} {
const requestId = getErrorRequestId(error);
return {
message: error.message,
stack: error.stack,
...(requestId ? { requestId } : {}),
};
}
/**
* Logger specifically for OpenAI API requests and responses
*/
@ -175,12 +209,7 @@ export class OpenAILogger {
timestamp: new Date().toISOString(),
request,
response: response || null,
error: error
? {
message: error.message,
stack: error.stack,
}
: null,
error: error ? serializeError(error) : null,
context: contextForPromptId(promptId),
system: {
hostname: os.hostname(),