question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Async Error Handler Running Synchronously

See original GitHub issue

I’m running into a pretty bizarre error while trying to upgrade our app to ember-concurrency@2.0.2 (from the latest pre-2.0.0 release).

It seems that the async error handler defined here is in fact running synchronously, and prempting our own error handling.

We have a swallow-error helper that we sometimes use for cases where an Ember Concurrency task would expect an error to be thrown and we use the derived error state on the task instance to show it to the user. Because we error will be “handled” in the UI itself, we want to swallow the error entirely.

swallow-error helper source

import { helper } from '@ember/component/helper';

/**
 * This helper is meant to be wrapped around another action that might throw an error that we want to suppress.
 *
 *   ```hbs
 *   <button {{on 'click' (swallow-error (perform this.someTaskThatMightThrow))}}>
 *     Click Me
 *   </button>
 *   ```
 */
export function swallowError([fn]) {
  return function callAndSwallowError(...args) {
    try {
      const response = fn(...args);

      if (response.catch) {
        return response.catch(function () {
          // Swallow async error
        });
      }

      return response;
    } catch (e) {
      // Swallow synchronous error
    }
  };
}

export default helper(swallowError);

In the current version of ember-concurrency that we’re using, this works just fine.

In ember-concurrency@2.0.2, it seems like the code here that should report the error if it was not already caught is being executed synchronously when it should be executed asynchronously

https://github.com/machty/ember-concurrency/blob/35a188cd86d322ae0b0c443d5b0c5cb009b1793c/addon/-private/external/task-instance/executor.js#L344-L348

I know it’s a challenge to grok a stack trace without much context, but this is what I’m seeing; a single synchronous trace from my debugger point inside the error-reporting callback that should be run asynchronously straight down to the function invocation inside callAndSwallowError.

CleanShot 2021-03-03 at 16 35 40@2x

I know that env.async is using join from the @ember/runloop package, which will insert the callback into the current queue. My guess is that Backburner is calling things in the current queue before proceeding with execution of the code in my helper… for some reason. My code isn’t doing anything directly with the runloop; there’s just the normal amount of wrapping that helper invocations have by default at play.

I tried to create a failing test case in the ember-concurrency repository but have been unable to get the same error to occur there just yet. I will post a PR with that once I have it.

I’m wondering whether a potential fix could be specifically scheduling the async callback into the next run loop, rather than using join which can insert it into the current “tick”.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
alexlafrosciacommented, Mar 17, 2021

Thanks again @maxfierke for putting so much effort into this admittedly-obscure bug!

0reactions
alexlafrosciacommented, Mar 16, 2021

Sounds good! Thanks for getting to the bottom of this!!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Error Handling in an async-sync system | Mercari Engineering
In Kubernetes, applications are run as self-contained replicas which do not share memory. So the responses cached by one replica can not be ......
Read more >
How to handle errors when you mixed up synchronous and ...
Error handling in synchronous code is done with the try-catch block and in asynchronous code, we handle errors with the help of catchError()....
Read more >
How to handle synchronous errors with async await?
I've been getting some unhandled rejections in my app, but I was pretty certain that all of my code is correctly wrapped with...
Read more >
Handling Synchronous and Asynchronous Errors in Express.js
Step Two: Asynchronous Errors. While Express will automagically catch synchronous errors and pass them to our custom error handler, asynchronous ...
Read more >
Error handling in JavaScript. Synchronous vs asynchronous ...
Error handling in JavaScript has been always straightforward, at least for synchronous code.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found