Petrus Vermaak
Petrus Vermaak

Reputation: 61

Cloudflare Worker to refresh page if error 520

We run our staging environment on a shared host. Occasionally we run into troubles with unknown errors. Cloudflare displays it as error 520 when the page loads.

It's not a resource problem, and we don't have server access. It really does not happen often, so I want to run a Cloudflare Worker that refreshes the page if there is a 520 error.

Does anyone know how to write this, please?

Upvotes: 0

Views: 878

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45161

Something like below should do it. Note that this doesn't "refresh" the page. Instead, the error page never reaches the user's browser at all, because on an error, the whole request is retried and the retry response goes to the browser instead.

Of course, it would be better to figure out why the error is happening. Cloudflare's error 520 means that your origin server is returning invalid responses to Cloudflare. Here is a page discussing what to do about it.

That said, while the problem is being investigated, a Worker can offer a convenient way to "sweep the problem under the rug" so that your visitors can access your site without problems.

export default {
  async fetch(request, env, ctx) {
    if (request.body) {
      // This request has a body, i.e. it's submitting some information to
      // the server, not just requesting a web page. If we wanted to be able
      // to retry such requests, we'd have to buffer the body so that we
      // can send it twice. That is expensive, so instead we'll just hope
      // that these requests (which are relatively uncommon) don't fail.
      // So we just pass the request to the server and return the response
      // nomally.
      return fetch(request);
    }

    // Try the request the first time.
    let response = await fetch(request);

    if (response.status == 520) {
      // The server returned status 520. Let's retry the request. But
      // we'll only retry once, since we don't want to get stuck in an
      // infinite retry loop.

      // Let's discard the previous response body. This is not strictly
      // required but it helps let the Workers Runtime know that it doesn't
      // need to hold open the HTTP connection for the failed request.
      await response.arrayBuffer();

      // OK, now we retry the request, and replace the response with the
      // new version.
      response = await fetch(request);
    }

    return response;
  }
}

Upvotes: 1

Related Questions