DEV: Handle CORS and other fetch failures for media-optimization-worker (#15364)

Occasionally there will be a misconfigured CORS rule or a different
network failure when loading one of the media optimization WASM scripts.
This commit handles load failures and sends a new installFailed message
from the service worker, so that we don't error and hold up the rest
of the uploads if this occurs; the worker will just not process anything
and will keep trying to install itself with subsequent uploads until it succeeds.

This commit also removes the redundant useUppy variable in the worker
this should have been removed a while ago in f70e6c302f
This commit is contained in:
Martin Brennan 2021-12-21 09:00:19 +10:00 committed by GitHub
parent 07436e9d8c
commit 995c514336
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 30 deletions

View File

@ -28,22 +28,21 @@ export default class MediaOptimizationWorkerService extends Service {
promiseResolvers = null; promiseResolvers = null;
async optimizeImage(data, opts = {}) { async optimizeImage(data, opts = {}) {
this.usingUppy = data.id && data.id.includes("uppy");
this.promiseResolvers = this.promiseResolvers || {}; this.promiseResolvers = this.promiseResolvers || {};
this.stopWorkerOnError = opts.hasOwnProperty("stopWorkerOnError") this.stopWorkerOnError = opts.hasOwnProperty("stopWorkerOnError")
? opts.stopWorkerOnError ? opts.stopWorkerOnError
: true; : true;
let file = this.usingUppy ? data : data.files[data.index]; let file = data;
if (!/(\.|\/)(jpe?g|png|webp)$/i.test(file.type)) { if (!/(\.|\/)(jpe?g|png|webp)$/i.test(file.type)) {
return this.usingUppy ? Promise.resolve() : data; return Promise.resolve();
} }
if ( if (
file.size < file.size <
this.siteSettings this.siteSettings
.composer_media_optimization_image_bytes_optimization_threshold .composer_media_optimization_image_bytes_optimization_threshold
) { ) {
return this.usingUppy ? Promise.resolve() : data; return Promise.resolve();
} }
await this.ensureAvailiableWorker(); await this.ensureAvailiableWorker();
@ -51,18 +50,14 @@ export default class MediaOptimizationWorkerService extends Service {
this.logIfDebug(`Transforming ${file.name}`); this.logIfDebug(`Transforming ${file.name}`);
this.currentComposerUploadData = data; this.currentComposerUploadData = data;
this.promiseResolvers[this.usingUppy ? file.id : file.name] = resolve; this.promiseResolvers[file.id] = resolve;
let imageData; let imageData;
try { try {
if (this.usingUppy) {
imageData = await fileToImageData(file.data); imageData = await fileToImageData(file.data);
} else {
imageData = await fileToImageData(file);
}
} catch (error) { } catch (error) {
this.logIfDebug(error); this.logIfDebug(error);
return this.usingUppy ? resolve() : resolve(data); return resolve();
} }
this.worker.postMessage( this.worker.postMessage(
@ -104,8 +99,9 @@ export default class MediaOptimizationWorkerService extends Service {
} }
async install() { async install() {
this.installPromise = new Promise((resolve) => { this.installPromise = new Promise((resolve, reject) => {
this.afterInstalled = resolve; this.afterInstalled = resolve;
this.failedInstall = reject;
this.logIfDebug("Installing worker."); this.logIfDebug("Installing worker.");
this.startWorker(); this.startWorker();
this.registerMessageHandler(); this.registerMessageHandler();
@ -152,13 +148,7 @@ export default class MediaOptimizationWorkerService extends Service {
`Finished optimization of ${optimizedFile.name} new size: ${optimizedFile.size}.` `Finished optimization of ${optimizedFile.name} new size: ${optimizedFile.size}.`
); );
if (this.usingUppy) {
this.promiseResolvers[e.data.fileId](optimizedFile); this.promiseResolvers[e.data.fileId](optimizedFile);
} else {
let data = this.currentComposerUploadData;
data.files[data.index] = optimizedFile;
this.promiseResolvers[optimizedFile.name](data);
}
break; break;
case "error": case "error":
@ -170,20 +160,18 @@ export default class MediaOptimizationWorkerService extends Service {
this.stopWorker(); this.stopWorker();
} }
if (this.usingUppy) {
this.promiseResolvers[e.data.fileId](); this.promiseResolvers[e.data.fileId]();
} else {
this.promiseResolvers[e.data.fileName](
this.currentComposerUploadData
);
}
break; break;
case "installed": case "installed":
this.logIfDebug("Worker installed."); this.logIfDebug("Worker installed.");
this.workerInstalled = true; this.workerInstalled = true;
this.afterInstalled(); this.afterInstalled();
this.afterInstalled = null; this.cleanupInstallPromises();
this.installPromise = null; break;
case "installFailed":
this.logIfDebug("Worker failed to install.");
this.failedInstall(e.data.errorMessage);
this.cleanupInstallPromises();
break; break;
default: default:
this.logIfDebug(`Sorry, we are out of ${e}.`); this.logIfDebug(`Sorry, we are out of ${e}.`);
@ -191,6 +179,12 @@ export default class MediaOptimizationWorkerService extends Service {
}; };
} }
cleanupInstallPromises() {
this.afterInstalled = null;
this.failedInstall = null;
this.installPromise = null;
}
logIfDebug(message) { logIfDebug(message) {
if (this.siteSettings.composer_media_optimization_debug_mode) { if (this.siteSettings.composer_media_optimization_debug_mode) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console

View File

@ -148,8 +148,12 @@ onmessage = async function (e) {
} }
break; break;
case "install": case "install":
try {
await loadLibs(e.data.settings); await loadLibs(e.data.settings);
postMessage({ type: "installed" }); postMessage({ type: "installed" });
} catch (error) {
postMessage({ type: "installFailed", errorMessage: error.message });
}
break; break;
default: default:
logIfDebug(`Sorry, we are out of ${e}.`); logIfDebug(`Sorry, we are out of ${e}.`);