# no-fallthrough

> Disallow `case` clauses that run on into the next one

A `case` that doesn't end with `break`, `return`, `throw`, `continue` or `process.exit()` keeps going into the code of the next `case`. A forgotten `break` runs code for a value it wasn't written for, and nothing fails at that line.

If you want the fallthrough, say so in a comment right before the next `case`. `// falls through`, `// fall-through`, `// fallthrough` and `// no break` all work, in any case. Several `case` labels in a row that share one body are allowed.

This rule is on by default.

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

## Configure

On by default as an error. To turn it off:

```toml bunfig.toml
[lint.rules]
"no-fallthrough" = "off" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"no-fallthrough" = ["error", {
  commentPattern = "(?i:falls?[\\s-]?through|no\\s?break)",
  allowEmptyCase = false,
  reportUnusedFallthroughComment = false,
}]
```

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

## Examples

Reported:

{/* bad */}
```js
switch (post.status) {
  case "draft":
    publish(post);
  case "published":
    notify(post);
    break;
}
```

Not reported:

{/* good */}
```js
switch (post.status) {
  case "draft":
    publish(post);
    break;
  case "published":
    notify(post);
    break;
}
```

`process.exit()` and `process.abort()` end a `case` too. With `--type-aware`, so does any call that returns `never`. With an ESLint config file they don't, as in ESLint.

{/* good */}
```js
switch (command) {
  case "help":
    printUsage();
    process.exit(0);
  case "version":
    console.log(version);
    break;
}
```

{/* good */}
```js
switch (post.status) {
  case "draft":
    publish(post);
  // falls through
  case "published":
  case "pinned":
    notify(post);
    break;
}
```

{/* good */}
```js
switch (post.status) {
  case "draft":
    publish(post);
  /* intentional fall-through */
  case "published":
    notify(post);
  // no break
  default:
    log(post);
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `commentPattern` | see below | A regular expression for the comment that allows a fallthrough. It replaces the default. |
| `allowEmptyCase` | `false` | Allow an empty `case` with a blank line before the next one. |
| `reportUnusedFallthroughComment` | `false` | Report a fallthrough comment after a `case` that can't fall through. |

The default `commentPattern` is `(?i:falls?[\s-]?through|no\s?break)`. With an ESLint config file it's ESLint's own, `falls?\s?through` in any case, which doesn't accept `fall-through` or `no break`.

{/* good {"options": [{"commentPattern": "break omitted"}]} */}
```js
switch (post.status) {
  case "draft":
    publish(post);
  // break omitted on purpose
  case "published":
    notify(post);
}
```

An empty `case` followed by a blank line looks like its body was deleted, so it's reported unless you set `allowEmptyCase`:

{/* bad */}
```js
switch (post.status) {
  case "draft":

  case "published":
    notify(post);
}
```

{/* good {"options": [{"allowEmptyCase": true}]} */}
```js
switch (post.status) {
  case "draft":

  case "published":
    notify(post);
}
```

With `reportUnusedFallthroughComment`, a comment that's no longer true is reported:

{/* bad {"options": [{"reportUnusedFallthroughComment": true}]} */}
```js
switch (post.status) {
  case "draft":
    publish(post);
    break;
  // falls through
  case "published":
    notify(post);
}
```
