From 99f2286a737f52831aef0f77699def844bd7a170 Mon Sep 17 00:00:00 2001 From: Surma Date: Tue, 25 May 2021 11:46:30 +0100 Subject: [PATCH] Better error handling for libSquoosh --- libsquoosh/src/index.js | 4 ++++ libsquoosh/src/worker_pool.js | 38 ++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libsquoosh/src/index.js b/libsquoosh/src/index.js index dfd00cc4..0a7a9b91 100644 --- a/libsquoosh/src/index.js +++ b/libsquoosh/src/index.js @@ -12,10 +12,13 @@ async function decodeFile({ file }) { let buffer; if (ArrayBuffer.isView(file)) { buffer = Buffer.from(file.buffer); + file = 'Binary blob'; } else if (file instanceof ArrayBuffer) { buffer = Buffer.from(file); + file = 'Binary blob'; } else if (file instanceof Buffer) { buffer = file; + file = 'Binary blob'; } else if (typeof file === 'string') { buffer = await fsp.readFile(file); } else { @@ -124,6 +127,7 @@ function handleJob(params) { */ class Image { constructor(workerPool, file) { + this.file = file; this.workerPool = workerPool; this.decoded = workerPool.dispatchJob({ operation: 'decode', file }); this.encodedWith = {}; diff --git a/libsquoosh/src/worker_pool.js b/libsquoosh/src/worker_pool.js index 57ebbfa7..45f85afe 100644 --- a/libsquoosh/src/worker_pool.js +++ b/libsquoosh/src/worker_pool.js @@ -8,17 +8,20 @@ function uuid() { } function jobPromise(worker, msg) { - return new Promise((resolve) => { + return new Promise((resolve, reject) => { const id = uuid(); worker.postMessage({ msg, id }); - worker.on('message', function f({ result, id: rid }) { + worker.on('message', function f({ error, result, id: rid }) { if (rid !== id) { return; } + if (error) { + reject(error); + return; + } worker.off('message', f); resolve(result); }); - worker.on('error', (error) => console.error('Worker error: ', error)); }); } @@ -45,14 +48,17 @@ export default class WorkerPool { await this._terminateAll(); return; } - const { msg, resolve } = value; + const { msg, resolve, reject } = value; const worker = await this._nextWorker(); - jobPromise(worker, msg).then((result) => { - resolve(result); - const writer = this.workerQueue.writable.getWriter(); - writer.write(worker); - writer.releaseLock(); - }); + jobPromise(worker, msg) + .then((result) => resolve(result)) + .catch((reason) => reject(reason)) + .finally(() => { + // Return the worker to the pool + const writer = this.workerQueue.writable.getWriter(); + writer.write(worker); + writer.releaseLock(); + }); } } @@ -77,9 +83,9 @@ export default class WorkerPool { } dispatchJob(msg) { - return new Promise((resolve) => { + return new Promise((resolve, reject) => { const writer = this.jobQueue.writable.getWriter(); - writer.write({ msg, resolve }); + writer.write({ msg, resolve, reject }); writer.releaseLock(); }); } @@ -87,8 +93,12 @@ export default class WorkerPool { static useThisThreadAsWorker(cb) { parentPort.on('message', async (data) => { const { msg, id } = data; - const result = await cb(msg); - parentPort.postMessage({ result, id }); + try { + const result = await cb(msg); + parentPort.postMessage({ result, id }); + } catch (e) { + parentPort.postMessage({ error: e.message, id }); + } }); } }