@@ -239,9 +239,23 @@ function buildConversionError(message: string, metadata: Partial<ConversionError
239239
240240const toErrorMessage = ( error : unknown ) : string => {
241241 const details = extractErrorDetails ( error ) ;
242+ const detailsMessage = details ?. message ?. toLowerCase ( ) ;
243+ if (
244+ detailsMessage &&
245+ ( detailsMessage . includes ( 'not valid json' ) || detailsMessage . includes ( 'unexpected token' ) )
246+ ) {
247+ return 'Invalid response format from feed creation API' ;
248+ }
242249 if ( details ?. message ) return details . message ;
243250 if ( error instanceof SyntaxError ) return 'Invalid response format from feed creation API' ;
244- if ( error instanceof Error ) return error . message ;
251+ if ( error instanceof Error ) {
252+ const normalizedMessage = error . message . toLowerCase ( ) ;
253+ if ( normalizedMessage . includes ( 'not valid json' ) || normalizedMessage . includes ( 'unexpected token' ) ) {
254+ return 'Invalid response format from feed creation API' ;
255+ }
256+
257+ return error . message ;
258+ }
245259 if ( typeof error === 'string' && error . trim ( ) ) return error ;
246260 return 'An unexpected error occurred' ;
247261} ;
@@ -291,33 +305,42 @@ function failConversion(
291305 throw buildConversionError ( message , metadata ) ;
292306}
293307
294- const extractErrorDetails = ( error : unknown ) : { message ?: string ; code ?: string } | null => {
308+ const extractErrorDetails = ( error : unknown ) : { message ?: string ; code ?: string ; status ?: number } | null => {
295309 if ( ! error || typeof error !== 'object' ) return null ;
296310
297311 const candidate = error as {
298- error ?: { message ?: unknown ; code ?: unknown } ;
312+ error ?: { message ?: unknown ; code ?: unknown ; status ?: unknown } ;
299313 message ?: unknown ;
300314 code ?: unknown ;
315+ status ?: unknown ;
301316 } ;
302317
303318 const message = normalizeString ( candidate . error ?. message ?? candidate . message ) ;
304319 const code = normalizeString ( candidate . error ?. code ?? candidate . code ) ;
305- return { message, code } ;
320+ const status = normalizeStatus ( candidate . error ?. status ?? candidate . status ) ;
321+ return { message, code, status } ;
306322} ;
307323
308324function retryableForFallback ( error : unknown ) : boolean {
309325 const details = extractErrorDetails ( error ) ;
310326 const errorCode = details ?. code ?. toUpperCase ( ) ;
327+ const status = details ?. status ;
311328 if ( errorCode && NON_RETRYABLE_ERROR_CODES . has ( errorCode ) ) return false ;
329+ if ( status && status < 500 ) return false ;
312330
313331 const message = ( details ?. message ?? toErrorMessage ( error ) ) . toLowerCase ( ) ;
314332 if ( ! details ?. code && ( message . includes ( 'unauthorized' ) || message . includes ( 'forbidden' ) ) ) return false ;
315333 if ( ! details ?. code && message . includes ( 'bad request' ) ) return false ;
316334 if ( message . includes ( 'access token' ) || message . includes ( 'authentication' ) ) return false ;
317335 if ( message . includes ( 'unsupported strategy' ) ) return false ;
318336 if ( message . includes ( 'invalid response format' ) ) return false ;
337+ if ( message . includes ( 'not valid json' ) || message . includes ( 'unexpected token' ) ) return false ;
338+ if ( message === 'network error' ) return false ;
339+ if ( error instanceof SyntaxError ) return false ;
319340
320- return ! networkFailure ( error , message ) ;
341+ if ( status && status >= 500 ) return true ;
342+ if ( message . includes ( 'failed to fetch http' ) ) return true ;
343+ return message . includes ( 'internal server error' ) || message . includes ( 'upstream timeout' ) ;
321344}
322345
323346function networkFailure ( error : unknown , normalizedMessage : string ) : boolean {
@@ -329,6 +352,10 @@ function normalizeString(value: unknown): string | undefined {
329352 return typeof value === 'string' && value . trim ( ) ? value : undefined ;
330353}
331354
355+ function normalizeStatus ( value : unknown ) : number | undefined {
356+ return typeof value === 'number' && Number . isFinite ( value ) ? value : undefined ;
357+ }
358+
332359function normalizePreviewText ( value ?: string ) : string | null {
333360 if ( ! value ) return null ;
334361
0 commit comments