# 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.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

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

Every option, set to its default:

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

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```js
function refresh() {
  loadItems().then(render);
}
```

Not reported:

{/* good */}
```js
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

| Option | Default | What it does |
| --- | --- | --- |
| `allowFinally` | `false` | Allow `finally()` after the `catch()`. |
| `allowThen` | `false` | Allow `then(a, b)` with two arguments as the end of a chain. |
| `allowThenStrict` | `false` | Allow `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:

{/* bad */}
```js
loadItems().then(render).catch(showError).finally(hideSpinner);
```

{/* good {"options": [{"allowFinally": true}]} */}
```js
loadItems().then(render).catch(showError).finally(hideSpinner);
```

{/* good {"options": [{"allowThen": true}]} */}
```js
loadItems().then(render, showError);
```

With `allowThenStrict`, the first argument must be `null`:

{/* good {"options": [{"allowThenStrict": true}]} */}
```js
loadItems().then(render).then(null, showError);
```

{/* bad {"options": [{"allowThenStrict": true}]} */}
```js
loadItems().then(render, showError);
```

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

{/* good {"options": [{"terminationMethod": ["catch", "done"]}]} */}
```js
loadItems().then(render).done();
loadItems().then(render).catch(showError);
```

{/* bad {"options": [{"terminationMethod": "done"}]} */}
```js
loadItems().then(render).catch(showError);
```
