workerpool icon indicating copy to clipboard operation
workerpool copied to clipboard

Empty error message in the .catch() phrase

Open tdoan2010 opened this issue 10 months ago • 2 comments

I'm using the pool to execute a function on the web browser. The code looks like this:

const workerPromise = $uploaderPool
        .exec('copyFile', [source, destination], {
          on: async (payload: FileUploadStatus) => {
            _updateTaskStatus(pathToFile, payload);
          }
        })
        .then(async (result: CopyInfo) => {
          await _registerFile(result, pathToFile, file.name, file.size, itemId);
        })
        .timeout(timeout)
        .catch(async (err) => {
          await _handleError(err, timeout, pathToFile, file.name, file.size, itemId);
        });

The copyFile function, as the name suggests, copies the file source to the destination. It also calculate the file checksum. The code works fine, but out of 95 thousand times, there were 3 times the .catch() phrase was called. When that happened, the err.message was empty (an empty string ''), so I have no idea what caused the problem.

It was definitely not timeout because I've tested for that case and I got expected error message.

There is no try - catch in the copyFile function, so the problem might be there. But as I said, without an error message, I'm clueless.

Inside the _handleError function, I have console.error(err). Following the trace, I found out that the error message was empty because of this line in the source code.

/**
 * Converts a serialized error to Error
 * @param {Object} obj Error that has been serialized and parsed to object
 * @return {Error} The equivalent Error.
 */
function objectToError (obj) {
  var temp = new Error('')  // <-- The error message was set to an empty string here
  var props = Object.keys(obj)

  for (var i = 0; i < props.length; i++) {
    temp[props[i]] = obj[props[i]]
  }

  return temp
}

Could you please fix it so that the error message is kept instead of setting it to an empty string? Or did I look at the wrong place?

tdoan2010 avatar Mar 08 '25 13:03 tdoan2010

Thanks for reporting. Do you have a minimal example demonstrating the issue?

This code was introduced in 447321ce0fcaa1b09fc9e6d6d13090e5886732f2, and was part of a serialization using serializerr. But the serializerr side in worker.js isn't there anymore, but the objectToError is still in place. So, I think we have to look again at the serialization/deserialization of errors and implement a proper fix for this.

Anyone able to help with this?

josdejong avatar Mar 12 '25 14:03 josdejong

I can look into this after I wrap up what I am currently working on. If someone can get to it before me feel free.

joshLong145 avatar Mar 15 '25 12:03 joshLong145

I was able to test this on 9.2.0 and I was not able to reproduce with a minimum example.

worker function

function throwsErr() {
  return new Promise(function(_, reject) {
    reject(new Error("I am an error"));
  });
}

pool execute call with timeout

pool.exec("throwsErr").timeout(1000).catch(function(err) {
    console.log(err);
});

When I run this I get a full error with message and stack trace starting from the line in my worker script where the error was thrown. So this tells me the deserializer is working as expected. Looking at the code I see we are copying object properties to the new error object created in objectToError.

Im not sure how the message in the Error object is not defined, is the stack trace correct by chance? If not this may suggest the serialized object was not passed in the result of the task execution somehow...

Update:

This code was introduced in https://github.com/josdejong/workerpool/commit/447321ce0fcaa1b09fc9e6d6d13090e5886732f2, and was part of a serialization using serializerr. But the serializerr side in worker.js isn't there anymore, but the objectToError is still in place. So, I think we have to look again at the serialization/deserialization of errors and implement a proper fix for this.

I think the deserializer is working as interned with the current serialization implemented within worker.js as the call to objectToError here is working as intended with its property copying implementation, or so it seems ... which is why I'm curious what the stack trace looks like.

joshLong145 avatar Jun 19 '25 00:06 joshLong145

Thanks for debugging this issue @joshLong145. Without additional feedback from @tdoan2010 we can't advance on this. I'll close this issue now due to a lack of response. @tdoan2010 please reopen if needed.

josdejong avatar Jul 02 '25 07:07 josdejong