fix: improve error handling and display in AiSdkToChunkAdapter (#11423)

* fix: improve error handling and display in AiSdkToChunkAdapter

* fix: test
This commit is contained in:
SuYao 2025-11-24 10:57:51 +08:00 committed by GitHub
parent 2c3338939e
commit 475f718efb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 43 deletions

View File

@ -386,8 +386,7 @@ export class AiSdkToChunkAdapter {
case 'error': case 'error':
this.onChunk({ this.onChunk({
type: ChunkType.ERROR, type: ChunkType.ERROR,
error: error: AISDKError.isInstance(chunk.error)
chunk.error instanceof AISDKError
? chunk.error ? chunk.error
: new ProviderSpecificError({ : new ProviderSpecificError({
message: formatErrorMessage(chunk.error), message: formatErrorMessage(chunk.error),

View File

@ -50,20 +50,17 @@ describe('error', () => {
}) })
describe('formatErrorMessage', () => { describe('formatErrorMessage', () => {
it('should format error with indentation and header', () => { it('should format error with message directly when message exists', () => {
console.error = vi.fn() console.error = vi.fn()
const error = new Error('Test error') const error = new Error('Test error')
const result = formatErrorMessage(error) const result = formatErrorMessage(error)
expect(result).toContain('Error Details:') // When error has a message property, it returns the message directly
expect(result).toContain(' {') expect(result).toBe('Test error')
expect(result).toContain(' "message": "Test error"')
expect(result).toContain(' }')
expect(result).not.toContain('"stack":')
}) })
it('should remove sensitive information and format with proper indentation', () => { it('should return message directly when error object has message property', () => {
console.error = vi.fn() console.error = vi.fn()
const error = { const error = {
@ -75,16 +72,11 @@ describe('error', () => {
const result = formatErrorMessage(error) const result = formatErrorMessage(error)
expect(result).toContain('Error Details:') // When error has a message property, it returns the message directly
expect(result).toContain(' {') expect(result).toBe('API error')
expect(result).toContain(' "message": "API error"')
expect(result).toContain(' }')
expect(result).not.toContain('Authorization')
expect(result).not.toContain('stack')
expect(result).not.toContain('request_id')
}) })
it('should handle errors during formatting with simple error message', () => { it('should handle errors during formatting and return placeholder message', () => {
console.error = vi.fn() console.error = vi.fn()
const problematicError = { const problematicError = {
@ -94,32 +86,23 @@ describe('error', () => {
} }
const result = formatErrorMessage(problematicError) const result = formatErrorMessage(problematicError)
expect(result).toContain('Error Details:') // When message property throws error, it's caught and set to '<Unable to access property>'
expect(result).toContain('"message": "<Unable to access property>"') expect(result).toBe('<Unable to access property>')
}) })
it('should handle non-serializable errors with simple error message', () => { it('should format error object without message property with full details', () => {
console.error = vi.fn() console.error = vi.fn()
const nonSerializableError = { const errorWithoutMessage = {
toString() { code: 500,
throw new Error('Cannot convert to string') status: 'Internal Server Error'
}
} }
try { const result = formatErrorMessage(errorWithoutMessage)
Object.defineProperty(nonSerializableError, 'toString', { // When no message property exists, it returns full error details
get() {
throw new Error('Cannot access toString')
}
})
} catch (e) {
// Ignore
}
const result = formatErrorMessage(nonSerializableError)
expect(result).toContain('Error Details:') expect(result).toContain('Error Details:')
expect(result).toContain('"toString": "<Unable to access property>"') expect(result).toContain('"code": 500')
expect(result).toContain('"status": "Internal Server Error"')
}) })
}) })

View File

@ -69,7 +69,7 @@ export function formatErrorMessage(error: unknown): string {
.split('\n') .split('\n')
.map((line) => ` ${line}`) .map((line) => ` ${line}`)
.join('\n') .join('\n')
return `Error Details:\n${formattedJson}` return detailedError.message ? detailedError.message : `Error Details:\n${formattedJson}`
} }
export function getErrorMessage(error: unknown): string { export function getErrorMessage(error: unknown): string {