5

I'm dealing with a web worker that needs to report back if an error has occured. Normally, I can use worker.onerror to listen to any errors that were thrown from the worker. However, when the error happens in a promise in the web worker, I can't figure out how to bubble the error back up to worker.onerror.

Excuse the odd code snippet, as this seems to be the only way to demonstrate worker behavior. (The worker is defined in the HTML section).

function getInlineJS() {
  var js = document.querySelector('[type="javascript/worker"]').textContent;
  var blob = new Blob([js], {
    "type": "text\/plain"
  });
  return URL.createObjectURL(blob);
}

var worker = new Worker(getInlineJS());

worker.onerror = function(err) {
  document.getElementById('errors').innerHTML += 
    "error " + err.message + '\n';
}

worker.onmessage = function (msg) {
  console.log("message recieved", msg);
  document.getElementById('messages').innerHTML += 
    "message " + msg.data + '\n';
}


worker.postMessage("run");
worker.postMessage("promise");
should write "Normal Error and In Promise Error" below and in console (promise error only occurs in console though): <br>

<pre id="errors">
</pre>

messages:
<pre id="messages">
</pre>

<script type="javascript/worker">
self.addEventListener("message", function(e) {
    /* demonstration of normal error bubbling to onerror */
    if (e.data == 'run') {
      throw new Error('Normal Error');
      return;
    }
    new Promise(function(resolve, reject) {
      /* some logic that breaks */
      throw new Error('In Promise Error');
    }).then(function(result) {
      
    }).catch(function(err) {
      /* QUESTION: HOW TO GET THIS ERROR OUT OF WORKER? */
      
      /* it logs to console just fine */
      console.log("In Promise Catch Error:", err);
      
      /* postMessage doesn't work for some reason */
      self.postMessage({error: err});
      
      /* and this doesn't bubble it to worker.onerror */
      throw err; /* doesn't bubble!! */
    });
});
</script>

How can I retrieve web worker errors that happen inside promises?

Tennyson H
  • 1,667
  • 14
  • 27
  • Instead of trying to use `onerror`, what about having the worker send a specific message when a particular error occurs? –  Oct 12 '16 at 07:59
  • @torazaburo i have updated the example snippet, can you take a look again? the `self.postMessage` doesn't work in the `.catch` section of the promise chain. – Tennyson H Oct 12 '16 at 18:26

1 Answers1

13

postMessage doesn't work for some reason

That's because you're returning an object instead of a string, change it to self.postMessage({error: err.message});

As for your second problem, you can use the setTimeout(function() { throw err; }); trick. More information about the situation and trick can be found here.

function getInlineJS() {
  var js = document.querySelector('[type="javascript/worker"]').textContent;
  var blob = new Blob([js], {
    "type": "text\/plain"
  });
  return URL.createObjectURL(blob);
}

var worker = new Worker(getInlineJS());

worker.onerror = function(err) {
  document.getElementById('errors').innerHTML += 
    "error " + err.message + '\n';
}

worker.onmessage = function (msg) {
  console.log("message recieved", msg);
  document.getElementById('messages').innerHTML += 
    "message " + msg.data + '\n';
}


worker.postMessage("run");
worker.postMessage("promise");
should write "Normal Error and In Promise Error" below and in console (promise error only occurs in console though): <br>

<pre id="errors">
</pre>

messages:
<pre id="messages">
</pre>

<script type="javascript/worker">
self.addEventListener("message", function(e) {
    /* demonstration of normal error bubbling to onerror */
    if (e.data == 'run') {
      throw new Error('Normal Error');
      return;
    }
    new Promise(function(resolve, reject) {
      /* some logic that breaks */
    
      throw new Error('In Promise Error');
    }).then(function(result) {
      
    }).catch(function(err) {
      /* it logs to console just fine */
      console.log("In Promise Catch Error:", err);
      
      /* postMessage works when you return a string. */
      self.postMessage({error: err.message});

       setTimeout(function() { throw err; }); 
    });
});
</script>
Community
  • 1
  • 1
Nick
  • 2,951
  • 2
  • 24
  • 47