mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #9058 from overleaf/jpa-error-handling-2nd-page
[web] improve error handling for pdf-caching GitOrigin-RevId: ddd65f2813fb08eb4493967071ee62d9742930cc
This commit is contained in:
parent
b4d12ff3c0
commit
f1487714b4
3 changed files with 42 additions and 16 deletions
|
@ -127,11 +127,23 @@ function PdfJsViewer({ url, pdfFile }) {
|
|||
setError(undefined)
|
||||
setStartFetch(performance.now())
|
||||
|
||||
pdfJsWrapper.loadDocument(url, pdfFile).catch(error => {
|
||||
console.error(error)
|
||||
const abortController = new AbortController()
|
||||
const handleFetchError = () => {
|
||||
if (abortController.signal.aborted) return
|
||||
// The error is already logged at the call-site with additional context.
|
||||
setError('rendering-error')
|
||||
})
|
||||
return () => pdfJsWrapper.abortDocumentLoading()
|
||||
}
|
||||
pdfJsWrapper
|
||||
.loadDocument({ url, pdfFile, abortController, handleFetchError })
|
||||
.catch(error => {
|
||||
if (abortController.signal.aborted) return
|
||||
console.error(error)
|
||||
setError('rendering-error')
|
||||
})
|
||||
return () => {
|
||||
abortController.abort()
|
||||
pdfJsWrapper.abortDocumentLoading()
|
||||
}
|
||||
}
|
||||
}, [pdfJsWrapper, url, pdfFile, setError, setStartFetch])
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ export function generatePdfCachingTransportFactory(PDFJS) {
|
|||
if (!enablePdfCaching && !trackPdfDownloadEnabled) {
|
||||
return () => null
|
||||
}
|
||||
let failedOnce = false
|
||||
const cached = new Set()
|
||||
const metrics = Object.assign(getPdfCachingMetrics(), {
|
||||
failedCount: 0,
|
||||
failedOnce: false,
|
||||
tooLargeOverheadCount: 0,
|
||||
tooManyRequestsCount: 0,
|
||||
cachedCount: 0,
|
||||
|
@ -27,12 +27,12 @@ export function generatePdfCachingTransportFactory(PDFJS) {
|
|||
new URLSearchParams(window.location.search).get('verify_chunks') === 'true'
|
||||
|
||||
class PDFDataRangeTransport extends PDFJS.PDFDataRangeTransport {
|
||||
constructor(url, pdfFile, reject) {
|
||||
constructor({ url, pdfFile, abortController, handleFetchError }) {
|
||||
super(pdfFile.size, new Uint8Array())
|
||||
this.url = url
|
||||
this.pdfFile = pdfFile
|
||||
this.reject = reject
|
||||
this.abortController = new AbortController()
|
||||
this.handleFetchError = handleFetchError
|
||||
this.abortController = abortController
|
||||
}
|
||||
|
||||
abort() {
|
||||
|
@ -59,17 +59,18 @@ export function generatePdfCachingTransportFactory(PDFJS) {
|
|||
abortSignal,
|
||||
})
|
||||
.catch(err => {
|
||||
if (abortSignal.aborted) return
|
||||
if (
|
||||
err.message === 'non successful response status: 404' &&
|
||||
OError.getFullInfo(err).url === this.url
|
||||
) {
|
||||
// Do not consider a 404 on the main pdf url as pdf caching failure.
|
||||
// Still, bail out during the initial launch phase.
|
||||
failedOnce = true
|
||||
metrics.failedOnce = true
|
||||
throw new PDFJS.MissingPDFException()
|
||||
}
|
||||
metrics.failedCount++
|
||||
failedOnce = true
|
||||
metrics.failedOnce = true
|
||||
if (!enablePdfCaching) {
|
||||
throw err // This was a fallback request already. Do not retry.
|
||||
}
|
||||
|
@ -79,25 +80,33 @@ export function generatePdfCachingTransportFactory(PDFJS) {
|
|||
return fallbackRequest({ url: this.url, start, end, abortSignal })
|
||||
})
|
||||
.then(blob => {
|
||||
if (abortSignal.aborted) return
|
||||
this.onDataRange(start, blob)
|
||||
})
|
||||
.catch(err => {
|
||||
if (abortSignal.aborted) return
|
||||
err = OError.tag(err, 'fatal pdf download error', errorInfo)
|
||||
console.error(err)
|
||||
if (!(err instanceof PDFJS.MissingPDFException)) {
|
||||
captureException(err, { tags: { fromPdfCaching: true } })
|
||||
}
|
||||
this.reject(err)
|
||||
// Signal error for (subsequent) page load.
|
||||
this.handleFetchError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return function (url, pdfFile, reject) {
|
||||
if (failedOnce) {
|
||||
return function ({ url, pdfFile, abortController, handleFetchError }) {
|
||||
if (metrics.failedOnce) {
|
||||
// Disable pdf caching once any fetch request failed.
|
||||
// Be trigger-happy here until we reached a stable state of the feature.
|
||||
return null
|
||||
}
|
||||
return new PDFDataRangeTransport(url, pdfFile, reject)
|
||||
return new PDFDataRangeTransport({
|
||||
url,
|
||||
pdfFile,
|
||||
abortController,
|
||||
handleFetchError,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ export default class PDFJSWrapper {
|
|||
}
|
||||
|
||||
// load a document from a URL
|
||||
loadDocument(url, pdfFile) {
|
||||
loadDocument({ url, pdfFile, abortController, handleFetchError }) {
|
||||
// cancel any previous loading task
|
||||
if (this.loadDocumentTask) {
|
||||
this.loadDocumentTask.destroy()
|
||||
|
@ -72,7 +72,12 @@ export default class PDFJSWrapper {
|
|||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const rangeTransport = this.genPdfCachingTransport(url, pdfFile, reject)
|
||||
const rangeTransport = this.genPdfCachingTransport({
|
||||
url,
|
||||
pdfFile,
|
||||
abortController,
|
||||
handleFetchError,
|
||||
})
|
||||
let rangeChunkSize = DEFAULT_RANGE_CHUNK_SIZE
|
||||
if (rangeTransport && pdfFile.size < 2 * DEFAULT_RANGE_CHUNK_SIZE) {
|
||||
// pdf.js disables the "bulk" download optimization when providing a
|
||||
|
|
Loading…
Reference in a new issue