@@ -64,6 +64,21 @@ vi.mock("puppeteer-chromium-resolver", () => ({
6464 } ) ,
6565} ) )
6666
67+ // Mock serialize-error
68+ vi . mock ( "serialize-error" , ( ) => ( {
69+ serializeError : vi . fn ( ( error ) => {
70+ if ( error instanceof Error ) {
71+ return { message : error . message , name : error . name }
72+ } else if ( typeof error === "string" ) {
73+ return { message : error }
74+ } else if ( error && typeof error === "object" && "message" in error ) {
75+ return { message : String ( error . message ) , name : "name" in error ? String ( error . name ) : undefined }
76+ } else {
77+ return { message : String ( error ) }
78+ }
79+ } ) ,
80+ } ) )
81+
6782describe ( "UrlContentFetcher" , ( ) => {
6883 let urlContentFetcher : UrlContentFetcher
6984 let mockContext : any
@@ -221,14 +236,43 @@ describe("UrlContentFetcher", () => {
221236
222237 it ( "should handle errors without message property" , async ( ) => {
223238 const errorWithoutMessage = { code : "UNKNOWN_ERROR" }
224- mockPage . goto . mockRejectedValueOnce ( errorWithoutMessage ) . mockResolvedValueOnce ( undefined )
239+ mockPage . goto . mockRejectedValueOnce ( errorWithoutMessage )
240+
241+ // serialize-error will convert this to a proper error with the object stringified
242+ await expect ( urlContentFetcher . urlToMarkdown ( "https://example.com" ) ) . rejects . toThrow ( )
243+
244+ // Should not retry for non-network errors
245+ expect ( mockPage . goto ) . toHaveBeenCalledTimes ( 1 )
246+ } )
247+
248+ it ( "should handle error objects with message property" , async ( ) => {
249+ const errorWithMessage = { message : "Custom error" , code : "CUSTOM_ERROR" }
250+ mockPage . goto . mockRejectedValueOnce ( errorWithMessage )
251+
252+ await expect ( urlContentFetcher . urlToMarkdown ( "https://example.com" ) ) . rejects . toThrow ( "Custom error" )
253+
254+ // Should not retry for error objects with message property (they're treated as known errors)
255+ expect ( mockPage . goto ) . toHaveBeenCalledTimes ( 1 )
256+ } )
257+
258+ it ( "should retry for error objects with network-related messages" , async ( ) => {
259+ const errorWithNetworkMessage = { message : "net::ERR_CONNECTION_REFUSED" , code : "NETWORK_ERROR" }
260+ mockPage . goto . mockRejectedValueOnce ( errorWithNetworkMessage ) . mockResolvedValueOnce ( undefined )
225261
226262 const result = await urlContentFetcher . urlToMarkdown ( "https://example.com" )
227263
228- // Should still retry since it can't determine the error type
264+ // Should retry for network-related errors even in non-Error objects
229265 expect ( mockPage . goto ) . toHaveBeenCalledTimes ( 2 )
230266 expect ( result ) . toBe ( "# Test content" )
231267 } )
268+
269+ it ( "should handle string errors" , async ( ) => {
270+ const stringError = "Simple string error"
271+ mockPage . goto . mockRejectedValueOnce ( stringError )
272+
273+ await expect ( urlContentFetcher . urlToMarkdown ( "https://example.com" ) ) . rejects . toThrow ( "Simple string error" )
274+ expect ( mockPage . goto ) . toHaveBeenCalledTimes ( 1 )
275+ } )
232276 } )
233277
234278 describe ( "closeBrowser" , ( ) => {
0 commit comments