1
0
Fork 0
mirror of https://github.com/overleaf/overleaf.git synced 2025-04-14 09:04:38 +00:00

Merge pull request from overleaf/jpa-service-worker-error-reporting

[misc] serviceWorker: add error reporting using postMessage API

GitOrigin-RevId: db021d4f5cd5b7b8a0026b92d412112f60499c0b
This commit is contained in:
Jessica Lawshe 2021-06-09 08:45:55 -05:00 committed by Copybot
parent fefa4ec391
commit 4c6933b5b8
3 changed files with 73 additions and 13 deletions
services/web/frontend/js

View file

@ -1,3 +1,6 @@
import { captureException } from '../../../infrastructure/error-reporter'
const OError = require('@overleaf/o-error')
let pendingWorkerSetup = Promise.resolve()
function supportsServiceWorker() {
@ -14,6 +17,26 @@ export function loadServiceWorker() {
.register('/serviceWorker.js', {
scope: '/project/',
})
.catch(error => console.warn('Cannot register serviceWorker', error))
.then(() => {
navigator.serviceWorker.addEventListener('message', event => {
let ctx
try {
ctx = JSON.parse(event.data)
} catch (e) {
return
}
if (!ctx || !ctx.error || !ctx.extra) return
const err = OError.tag(ctx.error, 'Error in serviceWorker')
const fullError = new Error()
fullError.name = err.name
fullError.message = err.message
fullError.stack = OError.getFullStack(err)
captureException(fullError, { extra: ctx.extra })
})
})
.catch(error =>
captureException(OError.tag(error, 'Cannot register serviceWorker'))
)
}
}

View file

@ -59,12 +59,8 @@ function sentryReporter() {
function nullReporter() {
return Promise.resolve({
captureException: error => {
console.error(error)
},
captureMessage: error => {
console.error(error)
},
captureException: console.error,
captureMessage: console.error,
})
}

View file

@ -1,4 +1,6 @@
import { v4 as uuid } from 'uuid'
const OError = require('@overleaf/o-error')
const COMPILE_REQUEST_MATCHER = /^\/project\/[0-9a-f]{24}\/compile$/
const PDF_REQUEST_MATCHER = /^\/project\/[0-9a-f]{24}\/.*\/output.pdf$/
const PDF_JS_CHUNK_SIZE = 128 * 1024
@ -253,10 +255,8 @@ function processPdfRequest(
fetch(url, init)
.then(response => {
if (!(response.status === 206 || response.status === 200)) {
throw new Error(
`could not fetch ${url} ${JSON.stringify(init)}: ${
response.status
}`
throw new OError(
'non successful response status: ' + response.status
)
}
const blobFetchDate = getServerTime(response)
@ -283,6 +283,9 @@ function processPdfRequest(
data: backFillObjectContext(chunk, arrayBuffer),
}
})
.catch(error => {
throw OError.tag(error, 'cannot fetch chunk', { url })
})
)
)
.then(responses => {
@ -343,7 +346,7 @@ function processPdfRequest(
})
})
.catch(error => {
console.error('Could not fetch partial pdf chunks', error)
reportError(event, OError.tag(error, 'failed to compose pdf response'))
return fetch(event.request)
})
)
@ -469,8 +472,19 @@ function getInterleavingDynamicChunks(chunks, start, end) {
return dynamicChunks
}
/**
* @param {FetchEvent} event
*/
function onFetchWithErrorHandling(event) {
try {
onFetch(event)
} catch (error) {
reportError(event, OError.tag(error, 'low level error in onFetch'))
}
}
// listen to all network requests
self.addEventListener('fetch', onFetch)
self.addEventListener('fetch', onFetchWithErrorHandling)
// complete setup ASAP
self.addEventListener('install', event => {
@ -479,3 +493,30 @@ self.addEventListener('install', event => {
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim())
})
/**
*
* @param {FetchEvent} event
* @param {Error} error
*/
function reportError(event, error) {
self.clients
.get(event.clientId)
.then(client => {
if (!client) {
// The client disconnected.
return
}
client.postMessage(
JSON.stringify({
extra: { url: event.request.url, info: OError.getFullInfo(error) },
error: {
name: error.name,
message: error.message,
stack: OError.getFullStack(error),
},
})
)
})
.catch(() => {})
}