mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(codex): truncate large unhandled notification logs (#626)
This commit is contained in:
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user