exceptions thrown in plugins are now properly caught in libresilientFetch (ref. #36)

master^2
Michał 'rysiek' Woźniak 2024-02-28 06:47:02 +00:00
rodzic 81dfaab7c5
commit 0932bf9b9f
1 zmienionych plików z 48 dodań i 41 usunięć

Wyświetl plik

@ -1026,48 +1026,55 @@ let initFromRequest = (req) => {
* reqInfo - instance of LibResilientResourceInfo
*/
let libresilientFetch = (plugin, url, init, reqInfo) => {
// status of the plugin
reqInfo.update({
method: (plugin && "name" in plugin) ? plugin.name : "unknown",
state: "running"
})
// log stuff
self.log('service-worker', "LibResilient Service Worker handling URL:", url,
'\n+-- init:', Object.getOwnPropertyNames(init).map(p=>`\n - ${p}: ${init[p]}`).join(''),
'\n+-- using method(s):', plugin.name
)
// starting the fetch...
// if it errors out immediately, at least we don't have to deal
// with a dangling promise timeout, set up below
let fetch_promise = plugin.fetch(url, init)
let timeout_promise, timeout_id
[timeout_promise, timeout_id] = promiseTimeout(
self.LibResilientConfig.defaultPluginTimeout,
false,
`LibResilient request using ${plugin.name} timed out after ${self.LibResilientConfig.defaultPluginTimeout}ms.`
)
// making sure there are no dangling promises etc
//
// this has to happen asynchronously
fetch_promise
// make sure the timeout is cancelled as soon as the promise resolves
// we do not want any dangling promises/timeouts after all!
.finally(()=>{
clearTimeout(timeout_id)
// we really need to catch any exceptions here
// otherwise other plugins will not run!
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch#gotchas_when_throwing_errors
try {
// status of the plugin
reqInfo.update({
method: (plugin && "name" in plugin) ? plugin.name : "unknown",
state: "running"
})
// no-op to make sure we don't end up with dangling rejected premises
.catch((e)=>{})
// race the plugin(s) vs. the timeout
return Promise
.race([
fetch_promise,
timeout_promise
]);
// log stuff
self.log('service-worker', "LibResilient Service Worker handling URL:", url,
'\n+-- init:', Object.getOwnPropertyNames(init).map(p=>`\n - ${p}: ${init[p]}`).join(''),
'\n+-- using method(s):', plugin.name
)
// starting the fetch...
// if it errors out immediately, at least we don't have to deal
// with a dangling promise timeout, set up below
let fetch_promise = plugin.fetch(url, init)
let timeout_promise, timeout_id
[timeout_promise, timeout_id] = promiseTimeout(
self.LibResilientConfig.defaultPluginTimeout,
false,
`LibResilient request using ${plugin.name} timed out after ${self.LibResilientConfig.defaultPluginTimeout}ms.`
)
// making sure there are no dangling promises etc
//
// this has to happen asynchronously
fetch_promise
// make sure the timeout is cancelled as soon as the promise resolves
// we do not want any dangling promises/timeouts after all!
.finally(()=>{
clearTimeout(timeout_id)
})
// no-op to make sure we don't end up with dangling rejected premises
.catch((e)=>{})
// race the plugin(s) vs. the timeout
return Promise
.race([
fetch_promise,
timeout_promise
]);
} catch(e) {
return Promise.reject(e)
}
}