# `PlugHTTPCache.StaleIfError`
[🔗](https://github.com/tanguilp/plug_http_cache/blob/main/lib/plug_http_cache/stale_if_error.ex#L1)

Return stale entries when backend fails

This module can help returning stale responses when the backend is temporarily
unusable (for instance when restarting the DB) or when some unexpected errors occur.
One of this known errors by Elixir developers is the

    ** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2655ms. This means requests are coming in and your connection pool cannot serve them fast enough. You can address this by:

        1. By tracking down slow queries and making sure they are running fast enough
        2. Increasing the pool_size (albeit it increases resource consumption)
        3. Allow requests to wait longer by increasing :queue_target and :queue_interval

    See DBConnection.start_link/2 for more information

ecto errors which occur when it is under intense stress.

Whenever a fresh response is found, it is returned by the `PlugHTTPCache` plug. Stale
responses, however, aren't. Stale responses are those whose expiration has been reached
but are still keep in the cache until the grace period is expired.

By default, the `http_cache` library caches cacheable responses 2 minutes, and keep
them 2 more minutes (which is called the *grace period*). By setting this module in your
plug pipeline, a stale response can be returned whenever an exception is raised by the
backend by adding this at the beginning of the router:

    use PlugHTTPCache.StaleIfError, ... % same options as when using `PlugHTTPCache`

When using it jointly with `Plug.ErrorHandler`, you should add it before:

    use PlugHTTPCache.StaleIfError, ... % same options as when using `PlugHTTPCache`
    use Plug.ErrorHandler

so that it is called before `Plug.ErrorHandler`'s generic error handling. In this case,
if a stale response if found, it is returned. Otherwise, the error handler of
`Plug.ErrorHandler` is called.

Staled responses are returned only when the `"stale-if-error"` cache control directive
is used, either in the request or in the response.

As very few clients use it, you probably want to use it server side by setting
this directive before returning the response in your controllers:

    conn
    |> put_resp_header("cache-control", "stale-if-error=600")
    ...

One can also not "cache" response, but still keep staled versions to keep some pages
showing even in case of serious trouble on the backend:

    conn
    |> put_resp_header("cache-control", "max-age=0, stale-if-error=600")
    ...

Such a response will not be reused except by this module, in case of error.

Note that as with the `Plug.ErrorHandler` module, error is reraised in any case.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
