@@ -22,6 +22,14 @@ interface FetchDecompressionError extends Error {
2222 path : string
2323}
2424
25+ /** Common shapes for non-APICallError provider errors carrying HTTP status */
26+ interface ErrorWithStatus {
27+ status ?: number
28+ statusCode ?: number
29+ response ?: { status ?: number ; statusCode ?: number }
30+ message ?: string
31+ }
32+
2533export namespace MessageV2 {
2634 export function isMedia ( mime : string ) {
2735 return mime . startsWith ( "image/" ) || mime === "application/pdf"
@@ -991,28 +999,27 @@ export namespace MessageV2 {
991999 ) . toObject ( )
9921000 case e instanceof Error : {
9931001 // Non-APICallError with HTTP status — treat 5xx as retryable.
1002+ const typed = e as Error & ErrorWithStatus
9941003 const code =
995- ( e as any ) . status ?? ( e as any ) . statusCode ??
996- ( e as any ) . response ?. status ?? ( e as any ) . response ?. statusCode ??
997- ( ( ) => {
998- try {
999- const obj = JSON . parse ( e . message )
1000- return obj ?. status ?? obj ?. statusCode
1001- } catch {
1002- return undefined
1003- }
1004- } ) ( )
1005- if ( typeof code === "number" && code >= 500 ) {
1006- let msg = e . message
1007- try {
1008- const obj = JSON . parse ( msg )
1009- if ( typeof obj ?. message === "string" ) msg = obj . message
1010- } catch { }
1004+ typed . status ?? typed . statusCode ??
1005+ typed . response ?. status ?? typed . response ?. statusCode
1006+ if ( typeof code === "number" && code >= 500 )
10111007 return new MessageV2 . APIError (
1012- { message : msg , statusCode : code , isRetryable : true } ,
1008+ { message : e . message , statusCode : code , isRetryable : true } ,
10131009 { cause : e } ,
10141010 ) . toObject ( )
1015- }
1011+ // Fallback: status may be embedded in a JSON error message.
1012+ try {
1013+ const obj = JSON . parse ( e . message ) as ErrorWithStatus
1014+ const jsonCode = obj ?. status ?? obj ?. statusCode
1015+ if ( typeof jsonCode === "number" && jsonCode >= 500 ) {
1016+ const msg = typeof obj ?. message === "string" ? obj . message : e . message
1017+ return new MessageV2 . APIError (
1018+ { message : msg , statusCode : jsonCode , isRetryable : true } ,
1019+ { cause : e } ,
1020+ ) . toObject ( )
1021+ }
1022+ } catch { }
10161023 return new NamedError . Unknown ( { message : e . message } , { cause : e } ) . toObject ( )
10171024 }
10181025 default :
@@ -1042,13 +1049,12 @@ export namespace MessageV2 {
10421049 } catch { }
10431050 // Plain-object 5xx — treat as retryable.
10441051 if ( typeof e === "object" && e !== null ) {
1045- const code =
1046- ( e as any ) . status ?? ( e as any ) . statusCode ??
1047- ( e as any ) . response ?. status ?? ( e as any ) . response ?. statusCode
1052+ const typed = e as ErrorWithStatus
1053+ const code = typed . status ?? typed . statusCode ?? typed . response ?. status ?? typed . response ?. statusCode
10481054 if ( typeof code === "number" && code >= 500 )
10491055 return new MessageV2 . APIError (
10501056 {
1051- message : typeof ( e as any ) . message === "string" ? ( e as any ) . message : JSON . stringify ( e ) ,
1057+ message : typeof typed . message === "string" ? typed . message : JSON . stringify ( e ) ,
10521058 statusCode : code ,
10531059 isRetryable : true ,
10541060 } ,
0 commit comments