Better error handling for libSquoosh

This commit is contained in:
Surma
2021-05-25 11:46:30 +01:00
parent f414092ea9
commit 99f2286a73
2 changed files with 28 additions and 14 deletions

View File

@@ -12,10 +12,13 @@ async function decodeFile({ file }) {
let buffer; let buffer;
if (ArrayBuffer.isView(file)) { if (ArrayBuffer.isView(file)) {
buffer = Buffer.from(file.buffer); buffer = Buffer.from(file.buffer);
file = 'Binary blob';
} else if (file instanceof ArrayBuffer) { } else if (file instanceof ArrayBuffer) {
buffer = Buffer.from(file); buffer = Buffer.from(file);
file = 'Binary blob';
} else if (file instanceof Buffer) { } else if (file instanceof Buffer) {
buffer = file; buffer = file;
file = 'Binary blob';
} else if (typeof file === 'string') { } else if (typeof file === 'string') {
buffer = await fsp.readFile(file); buffer = await fsp.readFile(file);
} else { } else {
@@ -124,6 +127,7 @@ function handleJob(params) {
*/ */
class Image { class Image {
constructor(workerPool, file) { constructor(workerPool, file) {
this.file = file;
this.workerPool = workerPool; this.workerPool = workerPool;
this.decoded = workerPool.dispatchJob({ operation: 'decode', file }); this.decoded = workerPool.dispatchJob({ operation: 'decode', file });
this.encodedWith = {}; this.encodedWith = {};

View File

@@ -8,17 +8,20 @@ function uuid() {
} }
function jobPromise(worker, msg) { function jobPromise(worker, msg) {
return new Promise((resolve) => { return new Promise((resolve, reject) => {
const id = uuid(); const id = uuid();
worker.postMessage({ msg, id }); worker.postMessage({ msg, id });
worker.on('message', function f({ result, id: rid }) { worker.on('message', function f({ error, result, id: rid }) {
if (rid !== id) { if (rid !== id) {
return; return;
} }
if (error) {
reject(error);
return;
}
worker.off('message', f); worker.off('message', f);
resolve(result); resolve(result);
}); });
worker.on('error', (error) => console.error('Worker error: ', error));
}); });
} }
@@ -45,10 +48,13 @@ export default class WorkerPool {
await this._terminateAll(); await this._terminateAll();
return; return;
} }
const { msg, resolve } = value; const { msg, resolve, reject } = value;
const worker = await this._nextWorker(); const worker = await this._nextWorker();
jobPromise(worker, msg).then((result) => { jobPromise(worker, msg)
resolve(result); .then((result) => resolve(result))
.catch((reason) => reject(reason))
.finally(() => {
// Return the worker to the pool
const writer = this.workerQueue.writable.getWriter(); const writer = this.workerQueue.writable.getWriter();
writer.write(worker); writer.write(worker);
writer.releaseLock(); writer.releaseLock();
@@ -77,9 +83,9 @@ export default class WorkerPool {
} }
dispatchJob(msg) { dispatchJob(msg) {
return new Promise((resolve) => { return new Promise((resolve, reject) => {
const writer = this.jobQueue.writable.getWriter(); const writer = this.jobQueue.writable.getWriter();
writer.write({ msg, resolve }); writer.write({ msg, resolve, reject });
writer.releaseLock(); writer.releaseLock();
}); });
} }
@@ -87,8 +93,12 @@ export default class WorkerPool {
static useThisThreadAsWorker(cb) { static useThisThreadAsWorker(cb) {
parentPort.on('message', async (data) => { parentPort.on('message', async (data) => {
const { msg, id } = data; const { msg, id } = data;
try {
const result = await cb(msg); const result = await cb(msg);
parentPort.postMessage({ result, id }); parentPort.postMessage({ result, id });
} catch (e) {
parentPort.postMessage({ error: e.message, id });
}
}); });
} }
} }