mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 09:37:28 +00:00
🐛 fix(fetch-sse): stop injecting contextBody into structured provider errors (#13477)
* 🐛 fix(fetch-sse): stop injecting contextBody into structured provider errors Structured errors (ProviderBizError etc.) already contain complete context. Spreading contextBody into their body overwrites fields like `provider` and pollutes the error structure that downstream renderers depend on. Fixes #13476 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ✅ test(fetch-sse): add regression test for structured error body pollution Ensures structured provider errors (e.g. ProviderBizError) are passed through unchanged without contextBody injection, and that contextBody is only applied to unknown/unstructured errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6ecae1bbd1
commit
8af28a778b
2 changed files with 45 additions and 3 deletions
|
|
@ -598,6 +598,42 @@ describe('fetchSSE', () => {
|
|||
expect(mockOnErrorHandle).toHaveBeenCalledWith(mockError);
|
||||
});
|
||||
|
||||
it('should NOT inject contextBody into structured provider errors (regression)', async () => {
|
||||
const mockOnErrorHandle = vi.fn();
|
||||
const mockError: ChatMessageError = {
|
||||
body: {
|
||||
error: {
|
||||
type: 'invalid_request_error',
|
||||
message: 'Invalid signature in thinking block',
|
||||
},
|
||||
provider: 'lobehub',
|
||||
errorType: 'ProviderBizError',
|
||||
},
|
||||
message: 'ProviderBizError',
|
||||
type: 'ProviderBizError',
|
||||
};
|
||||
|
||||
(fetchEventSource as any).mockImplementationOnce(
|
||||
(url: string, options: FetchEventSourceInit) => {
|
||||
options.onerror!(mockError);
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
await fetchSSE('/', {
|
||||
onErrorHandle: mockOnErrorHandle,
|
||||
requestContext: { provider: 'openai', model: 'gpt-4o' },
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
expect(mockOnErrorHandle).toHaveBeenCalledWith(mockError);
|
||||
const receivedError = mockOnErrorHandle.mock.calls[0][0];
|
||||
expect(receivedError.body).not.toHaveProperty('elapsedMs');
|
||||
expect(receivedError.body).not.toHaveProperty('networkStatus');
|
||||
expect(receivedError.body).not.toHaveProperty('model');
|
||||
expect(receivedError.body.provider).toBe('lobehub');
|
||||
});
|
||||
|
||||
it('should call onErrorHandle when Unknown error is thrown', async () => {
|
||||
const mockOnErrorHandle = vi.fn();
|
||||
const mockError = new Error('Unknown error');
|
||||
|
|
@ -609,7 +645,10 @@ describe('fetchSSE', () => {
|
|||
);
|
||||
|
||||
try {
|
||||
await fetchSSE('/', { onErrorHandle: mockOnErrorHandle });
|
||||
await fetchSSE('/', {
|
||||
onErrorHandle: mockOnErrorHandle,
|
||||
requestContext: { provider: 'openai', model: 'gpt-4o' },
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
expect(mockOnErrorHandle).toHaveBeenCalledWith({
|
||||
|
|
@ -618,7 +657,10 @@ describe('fetchSSE', () => {
|
|||
body: {
|
||||
message: 'Unknown error',
|
||||
name: 'Error',
|
||||
stack: expect.any(String),
|
||||
provider: 'openai',
|
||||
model: 'gpt-4o',
|
||||
elapsedMs: expect.any(Number),
|
||||
networkStatus: expect.any(Boolean),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ export const fetchSSE = async (url: string, options: RequestInit & FetchSSEOptio
|
|||
|
||||
options.onErrorHandle?.(
|
||||
error.type
|
||||
? { ...error, body: { ...error.body, ...contextBody } }
|
||||
? error
|
||||
: {
|
||||
body: {
|
||||
message: error.message,
|
||||
|
|
|
|||
Loading…
Reference in a new issue