# When something breaks

Every site eventually runs code that fails. What matters is what the
visitor sees, what the owner can find out, and how long the site stays
down. Minn answers those three separately.

## The pages

A failure never puts detail on the page. The cause goes to the log as one
line, and the visitor gets a plain statement that something went wrong. A
REST client gets the same refusal as JSON, with status 500 and the code
`internal_server_error`. A site that has switched debug display on sees the
cause as well, because it asked to.

## Recovery

A plugin that keeps killing the site as it boots does not have to keep the
site down.

When code in `plugins/` kills a request while the site is booting, the file
it died in names the plugin it belongs to. One failure is only noted: a
single request can be a crafted one, and pausing a plugin is a decision for
the whole site. A second failure from the same plugin within ten minutes
pauses it. The next request loads without it, so the site comes back on its
own, usually before anyone has noticed, with the broken plugin sitting out
rather than the whole site sitting down.

A failure after the site has booted, in a route, a shortcode or a template,
gets the error page and a line in the log. It never pauses anything.

Nothing loads a paused plugin again until someone says so:

```
wp minn recovery                          # what is paused, and why
wp minn recovery resume <plugin-file>     # let one plugin back in
wp minn recovery resume-all               # let everything back in
```

The paused list lives in the `paused_plugins` option, keyed by plugin file,
with the file, line and message that paused it.

Two limits worth stating. Minn blames only what lives in `plugins/`: a fatal
in the engine itself is not a plugin's fault and pausing something would not
fix it, so nothing is paused and the error page stands. And a fatal that
happens before the database is reachable cannot be recorded at all, because
there is nowhere to record it.

## What the log holds

One line per failure, naming the class, the message, the file and the
line, and a line for each step recovery takes:

```
Minn Engine: Error: Call to undefined function acme_gateway() in /wp-content/plugins/acme-pay/acme-pay.php:38
Minn Engine: plugin acme-pay/acme-pay.php failed while booting; a second failure within ten minutes pauses it
Minn Engine: paused plugin acme-pay/acme-pay.php after a second fatal error while booting; resume it with wp minn recovery resume
```

A plugin that will not even parse fails as it loads. Minn skips it, the site
keeps serving, and the log names the plugin and the error.
