Add timeouts to file-view-text fetch requests (#15690)

* Add timeouts to file-view-text fetch requests with useAbortController for graceful cleanup

* Add context to error log for file-view-text content fetching

GitOrigin-RevId: de50e5d99f22b219eb31425ab39ca35d84300625
This commit is contained in:
Thomas 2023-11-09 17:35:31 +01:00 committed by Copybot
parent 0639f266d8
commit 3ff58aa318

View file

@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { useProjectContext } from '../../../shared/context/project-context'
import { debugConsole } from '@/utils/debugging'
import useAbortController from '../../../shared/hooks/use-abort-controller'
const MAX_FILE_SIZE = 2 * 1024 * 1024
@ -14,12 +15,20 @@ export default function FileViewText({ file, onLoad, onError }) {
const [shouldShowDots, setShouldShowDots] = useState(false)
const [inFlight, setInFlight] = useState(false)
const fetchContentLengthController = useAbortController()
const fetchDataController = useAbortController()
useEffect(() => {
if (inFlight) {
return
}
let path = `/project/${projectId}/file/${file.id}`
fetch(path, { method: 'HEAD' })
const fetchContentLengthTimeout = setTimeout(
() => fetchContentLengthController.abort(),
10000
)
let fetchDataTimeout
fetch(path, { method: 'HEAD', signal: fetchContentLengthController.signal })
.then(response => {
if (!response.ok) throw new Error('HTTP Error Code: ' + response.status)
return response.headers.get('Content-Length')
@ -35,7 +44,9 @@ export default function FileViewText({ file, onLoad, onError }) {
if (maxSize != null) {
path += `?range=0-${maxSize}`
}
return fetch(path).then(response => {
fetchDataTimeout = setTimeout(() => fetchDataController.abort(), 60000)
return fetch(path, { signal: fetchDataController.signal }).then(
response => {
return response.text().then(text => {
if (truncated) {
text = text.replace(/\n.*$/, '')
@ -45,16 +56,27 @@ export default function FileViewText({ file, onLoad, onError }) {
onLoad()
setShouldShowDots(truncated)
})
})
}
)
})
.catch(err => {
debugConsole.error(err)
debugConsole.error('Error fetching file contents', err)
onError()
})
.finally(() => {
setInFlight(false)
clearTimeout(fetchContentLengthTimeout)
clearTimeout(fetchDataTimeout)
})
}, [projectId, file.id, onError, onLoad, inFlight])
}, [
projectId,
file.id,
onError,
onLoad,
inFlight,
fetchContentLengthController,
fetchDataController,
])
return (
<div>
{textPreview && (