fix(codex): truncate large unhandled notification logs (#626)

This commit is contained in:
MapleStoryIdle
2026-05-16 07:47:36 +08:00
committed by GitHub
parent c07b3a2ed2
commit 84ba7044a8
2 changed files with 63 additions and 2 deletions
@@ -1,4 +1,5 @@
import { describe, expect, it } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
import { logger } from '@/ui/logger';
import { AppServerEventConverter } from './appServerEventConverter';
describe('AppServerEventConverter', () => {
@@ -742,4 +743,27 @@ describe('AppServerEventConverter', () => {
]);
});
it('truncates large unhandled notification payloads before logging', () => {
const converter = new AppServerEventConverter();
const debug = vi.spyOn(logger, 'debug').mockImplementation(() => undefined);
const largeImageResult = 'a'.repeat(4096);
const events = converter.handleNotification('item/completed', {
item: {
id: 'image-1',
type: 'imageGeneration',
result: largeImageResult,
savedPath: '/tmp/image.png'
}
});
expect(events).toEqual([]);
expect(debug).toHaveBeenCalledTimes(1);
const logged = debug.mock.calls[0]?.[1] as { params?: { item?: { result?: string; savedPath?: string } } };
expect(logged.params?.item?.result).not.toBe(largeImageResult);
expect(logged.params?.item?.result).toContain('[truncated 3584 chars for logs]');
expect(logged.params?.item?.savedPath).toBe('/tmp/image.png');
debug.mockRestore();
});
});
+38 -1
View File
@@ -228,6 +228,43 @@ function addEventScope(events: ConvertedEvent[], scope: Record<string, unknown>)
}));
}
const MAX_UNHANDLED_LOG_STRING_LENGTH = 512;
const MAX_UNHANDLED_LOG_ARRAY_LENGTH = 20;
const MAX_UNHANDLED_LOG_DEPTH = 8;
function sanitizeUnhandledNotificationLogValue(value: unknown, depth: number = 0): unknown {
if (typeof value === 'string') {
if (value.length <= MAX_UNHANDLED_LOG_STRING_LENGTH) {
return value;
}
return `${value.slice(0, MAX_UNHANDLED_LOG_STRING_LENGTH)}... [truncated ${value.length - MAX_UNHANDLED_LOG_STRING_LENGTH} chars for logs]`;
}
if (Array.isArray(value)) {
const items = value
.slice(0, MAX_UNHANDLED_LOG_ARRAY_LENGTH)
.map((item) => sanitizeUnhandledNotificationLogValue(item, depth + 1));
if (value.length > MAX_UNHANDLED_LOG_ARRAY_LENGTH) {
items.push(`... [truncated ${value.length - MAX_UNHANDLED_LOG_ARRAY_LENGTH} array items for logs]`);
}
return items;
}
if (!value || typeof value !== 'object') {
return value;
}
if (depth >= MAX_UNHANDLED_LOG_DEPTH) {
return '[truncated nested object for logs]';
}
const result: Record<string, unknown> = {};
for (const [key, nestedValue] of Object.entries(value)) {
result[key] = sanitizeUnhandledNotificationLogValue(nestedValue, depth + 1);
}
return result;
}
function normalizeCollabAgentToolName(value: unknown): string | null {
const raw = asString(value);
if (!raw) return null;
@@ -899,7 +936,7 @@ export class AppServerEventConverter {
}
}
logger.debug('[AppServerEventConverter] Unhandled notification', { method, params });
logger.debug('[AppServerEventConverter] Unhandled notification', sanitizeUnhandledNotificationLogValue({ method, params }));
return events;
}