Description
The problem is that QUnit chooses to crash tests unconditionally on an unhandled rejected promise.
Say, I've got this basic setup:
@dropTask
@waitFor
async _submitTask(): Promise<void> {
return await this.product.save();
}
submitTask = taskFor(this._submitTask);
This is perfectly valid code: it adheres to Ember Concurrency guidelines and it works flawlessly in production.
The problem happens when I try to test the failed state:
// ember-cli-mirage
this.server.post('/products', { message: 'There was an error' }, 500);
await click('button');
assert.equal(
find('.message').textContent.trim(),
'Something wrong happened: "Ember Data Request POST /api/saved-configurations returned a 500'
);
This is also a perfectly valid test, yet QUnit chooses to crash it because the promise generated by the perform
helper has been rejected and not handled.
The workaround is to replace this:
With this:
@action
async submit(): Promise<void> {
try {
await this.submitTask.perform();
} catch(e) {
// We don't want tests to unconditionally crash when this happens.
// The error will be handled by `submitTask.last.isError`
}
}
This is a huge bummer, because this runtime boilerplate is absolutely unnecessary for production and only exists to please QUnit.
I believe this is an issue with QUnit and has nothing to do with Ember Concurrency. Yet, @rwjblue has confirmed that this QUnit behavior is intended and that QUnit was deliberately modified to behave like that.
Given that this QUnit behavior is official, it basically renders the perform
helper faulty as it would crash the tests for failed and cancelled EC tasks.
I would like to start a discussion regarding what can be done to mitigate this. E. g. can the perform
helper internally catch the promise returned by the task?
CC @simonihmig