promise/catch-or-return

Require a promise chain to end with catch() or to be returned

When a promise chain is a statement by itself, no other code can handle its errors. Without a catch() at the end, a failure becomes an unhandled rejection.

The rule checks statements that call then(), catch(), finally() or a static method such as Promise.all(). A chain that's returned, awaited or assigned isn't reported, because the code that receives it can handle the error. Cypress chains that start with cy. aren't reported either.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"promise/catch-or-return" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"promise/catch-or-return" = ["error", {
  allowFinally = false,
  allowThen = false,
  allowThenStrict = false,
  terminationMethod = "catch",
}]

Examples#

example.js1 problem
function refresh() {
  loadItems().then(render);
}
example.jsNo problems
function refresh() {
  loadItems().then(render).catch(showError);
}

function refreshLater() {
  return loadItems().then(render);
}

async function refreshNow() {
  await loadItems().then(render);
}

cy.get("button").then(click);

Options#

OptionDefaultWhat it does
allowFinallyfalseAllow finally() after the catch().
allowThenfalseAllow then(a, b) with two arguments as the end of a chain.
allowThenStrictfalseAllow then(null, b) as the end of a chain.
terminationMethod"catch"The method, or a list of methods, that a chain must end with.

By default, the catch() must come last, so this is reported:

example.js1 problem
loadItems().then(render).catch(showError).finally(hideSpinner);
example.jswith { "allowFinally": true }No problems
loadItems().then(render).catch(showError).finally(hideSpinner);
example.jswith { "allowThen": true }No problems
loadItems().then(render, showError);

With allowThenStrict, the first argument must be null:

example.jswith { "allowThenStrict": true }No problems
loadItems().then(render).then(null, showError);
example.jswith { "allowThenStrict": true }1 problem
loadItems().then(render, showError);

terminationMethod replaces catch. List "catch" too if you want to keep it:

example.jswith { "terminationMethod": ["catch", "done"] }No problems
loadItems().then(render).done();
loadItems().then(render).catch(showError);
example.jswith { "terminationMethod": "done" }1 problem
loadItems().then(render).catch(showError);