Async Error Handler Running Synchronously
See original GitHub issueI’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
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
.
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:
- Created 3 years ago
- Comments:12 (7 by maintainers)
Top GitHub Comments
Thanks again @maxfierke for putting so much effort into this admittedly-obscure bug!
Sounds good! Thanks for getting to the bottom of this!!