From ead265c1b98883f7971eb454b14fc81442e0589f Mon Sep 17 00:00:00 2001 From: "Yuichiro Tachibana (Tsuchiya)" Date: Thu, 12 Oct 2023 15:49:52 +0900 Subject: [PATCH] Lite: Convert an error object caught in the worker to be cloneable (#5838) * Convert an error object caught in the worker to be cloneable so it can be delegated to the main thread properly * add changeset * Add a comment * Fix the error serialization for the inter-thread messaging * Fix reply error message --------- Co-authored-by: gradio-pr-bot Co-authored-by: Ali Abdalla --- .changeset/chatty-berries-flash.md | 5 +++++ js/wasm/src/webworker/index.ts | 21 +++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 .changeset/chatty-berries-flash.md diff --git a/.changeset/chatty-berries-flash.md b/.changeset/chatty-berries-flash.md new file mode 100644 index 0000000000..55ebdbfd18 --- /dev/null +++ b/.changeset/chatty-berries-flash.md @@ -0,0 +1,5 @@ +--- +"@gradio/wasm": minor +--- + +feat:Lite: Convert an error object caught in the worker to be cloneable diff --git a/js/wasm/src/webworker/index.ts b/js/wasm/src/webworker/index.ts index 6578fe02ab..43d9af3b29 100644 --- a/js/wasm/src/webworker/index.ts +++ b/js/wasm/src/webworker/index.ts @@ -314,10 +314,27 @@ self.onmessage = async (event: MessageEvent): Promise => { } } } catch (error) { + console.error(error); + + if (!(error instanceof Error)) { + throw error; + } + + // The `error` object may contain non-serializable properties such as function (for example Pyodide.FS.ErrnoError which has a `.setErrno` function), + // so it must be converted to a plain object before sending it to the main thread. + // Otherwise, the following error will be thrown: + // `Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'MessagePort': # could not be cloned.` + // Also, the JSON.stringify() and JSON.parse() approach like https://stackoverflow.com/a/42376465/13103190 + // does not work for Error objects because the Error object is not enumerable. + // So we use the following approach to clone the Error object. + const cloneableError = new Error(error.message); + cloneableError.name = error.name; + cloneableError.stack = error.stack; + const replyMessage: ReplyMessageError = { type: "reply:error", - error: error as Error - }; + error: cloneableError, + } messagePort.postMessage(replyMessage); } };