@@ -24,6 +24,16 @@ export type ErrorObject = {
2424 code ?: string
2525 /** Optional raw error object */
2626 rawError ?: string
27+ /** Response body from API errors (AI SDK APICallError) */
28+ responseBody ?: string
29+ /** URL that was called (API errors) */
30+ url ?: string
31+ /** Whether the error is retryable (API errors) */
32+ isRetryable ?: boolean
33+ /** Request body values that were sent (API errors) - stringified for safety */
34+ requestBodyValues ?: string
35+ /** Cause of the error, if nested */
36+ cause ?: ErrorObject
2737}
2838
2939export function success < T > ( value : T ) : Success < T > {
@@ -45,6 +55,37 @@ interface ExtendedErrorProperties {
4555 status ?: number
4656 statusCode ?: number
4757 code ?: string
58+ // API error properties (AI SDK APICallError, etc.)
59+ responseBody ?: string
60+ url ?: string
61+ isRetryable ?: boolean
62+ requestBodyValues ?: Record < string , unknown >
63+ cause ?: unknown
64+ }
65+
66+ /**
67+ * Safely stringify an object, handling circular references and large objects.
68+ */
69+ function safeStringify ( value : unknown , maxLength = 10000 ) : string | undefined {
70+ if ( value === undefined || value === null ) return undefined
71+ if ( typeof value === 'string' ) return value . slice ( 0 , maxLength )
72+ try {
73+ const seen = new WeakSet ( )
74+ const str = JSON . stringify (
75+ value ,
76+ ( _ , val ) => {
77+ if ( typeof val === 'object' && val !== null ) {
78+ if ( seen . has ( val ) ) return '[Circular]'
79+ seen . add ( val )
80+ }
81+ return val
82+ } ,
83+ 2 ,
84+ )
85+ return str ?. slice ( 0 , maxLength )
86+ } catch {
87+ return '[Unable to stringify]'
88+ }
4889}
4990
5091export function getErrorObject (
@@ -53,6 +94,28 @@ export function getErrorObject(
5394) : ErrorObject {
5495 if ( error instanceof Error ) {
5596 const extError = error as Error & Partial < ExtendedErrorProperties >
97+
98+ // Extract responseBody - could be string or object
99+ let responseBody : string | undefined
100+ if ( extError . responseBody !== undefined ) {
101+ responseBody = safeStringify ( extError . responseBody )
102+ }
103+
104+ // Extract requestBodyValues - typically an object, stringify for logging
105+ let requestBodyValues : string | undefined
106+ if (
107+ extError . requestBodyValues !== undefined &&
108+ typeof extError . requestBodyValues === 'object'
109+ ) {
110+ requestBodyValues = safeStringify ( extError . requestBodyValues )
111+ }
112+
113+ // Extract cause - recursively convert to ErrorObject if present
114+ let cause : ErrorObject | undefined
115+ if ( extError . cause !== undefined ) {
116+ cause = getErrorObject ( extError . cause , options )
117+ }
118+
56119 return {
57120 name : error . name ,
58121 message : error . message ,
@@ -64,8 +127,17 @@ export function getErrorObject(
64127 : undefined ,
65128 code : typeof extError . code === 'string' ? extError . code : undefined ,
66129 rawError : options . includeRawError
67- ? JSON . stringify ( error , null , 2 )
130+ ? safeStringify ( error )
68131 : undefined ,
132+ // API error fields
133+ responseBody,
134+ url : typeof extError . url === 'string' ? extError . url : undefined ,
135+ isRetryable :
136+ typeof extError . isRetryable === 'boolean'
137+ ? extError . isRetryable
138+ : undefined ,
139+ requestBodyValues,
140+ cause,
69141 }
70142 }
71143
0 commit comments