@@ -39,16 +39,24 @@ async function fetchFileContentForDiff(
3939 filePath : string ,
4040 signal ?: AbortSignal ,
4141) : Promise < string | null > {
42+ const url = `https://cdn.jsdelivr.net/npm/${ packageName } @${ version } /${ filePath } `
43+ const controller = new AbortController ( )
44+ const timeoutId = setTimeout ( ( ) => controller . abort ( ) , DIFF_TIMEOUT )
45+ if ( signal ) {
46+ signal . addEventListener ( 'abort' , ( ) => controller . abort ( signal . reason as any ) , { once : true } )
47+ }
48+
4249 try {
43- const url = `https://cdn.jsdelivr.net/npm/${ packageName } @${ version } /${ filePath } `
44- const response = await fetch ( url , { signal } )
50+ const response = await fetch ( url , { signal : controller . signal } )
4551
4652 if ( ! response . ok ) {
4753 if ( response . status === 404 ) return null
48- throw new Error ( `Failed to fetch: ${ response . status } ` )
54+ throw createError ( {
55+ statusCode : response . status >= 500 ? 502 : response . status ,
56+ message : `Failed to fetch file (${ response . status } )` ,
57+ } )
4958 }
5059
51- // Check content-length
5260 const contentLength = response . headers . get ( 'content-length' )
5361 if ( contentLength && parseInt ( contentLength , 10 ) > MAX_DIFF_FILE_SIZE ) {
5462 throw createError ( {
@@ -71,7 +79,18 @@ async function fetchFileContentForDiff(
7179 if ( error && typeof error === 'object' && 'statusCode' in error ) {
7280 throw error
7381 }
74- return null
82+ if ( ( error as Error ) ?. name === 'AbortError' ) {
83+ throw createError ( {
84+ statusCode : 504 ,
85+ message : 'Diff request timed out while fetching file' ,
86+ } )
87+ }
88+ throw createError ( {
89+ statusCode : 502 ,
90+ message : 'Failed to fetch file for diff' ,
91+ } )
92+ } finally {
93+ clearTimeout ( timeoutId )
7594 }
7695}
7796
@@ -116,12 +135,15 @@ export default defineCachedEventHandler(
116135
117136 try {
118137 // Validate inputs
119- const { packageName, fromVersion, toVersion, filePath } = v . parse ( PackageFileDiffQuerySchema , {
120- packageName : rawPackageName ,
121- fromVersion : range . from ,
122- toVersion : range . to ,
123- filePath : rawFilePath ,
124- } )
138+ const { packageName, fromVersion, toVersion, filePath } = v . parse (
139+ PackageFileDiffQuerySchema ,
140+ {
141+ packageName : rawPackageName ,
142+ fromVersion : range . from ,
143+ toVersion : range . to ,
144+ filePath : rawFilePath ,
145+ } ,
146+ )
125147
126148 // Set up abort controller for timeout
127149 const controller = new AbortController ( )
@@ -178,9 +200,7 @@ export default defineCachedEventHandler(
178200 }
179201
180202 // Insert skip blocks and count stats
181- const hunkOnly = diff . hunks . filter (
182- ( h ) : h is DiffHunk => h . type === 'hunk' ,
183- )
203+ const hunkOnly = diff . hunks . filter ( ( h ) : h is DiffHunk => h . type === 'hunk' )
184204 const hunksWithSkips = insertSkipBlocks ( hunkOnly )
185205 const stats = countDiffStats ( hunksWithSkips )
186206
0 commit comments