Let's talk HTTP status codes and Service Workers. A 🧵.

4xx HTTP codes are "client error" codes: the server is telling the client (often the browser) that the client did something wrong: requested a resource that doesn't exist, or which is forbidden, for example.

5xx HTTP codes are "server error" codes: the server is informing the client that the server did a boo boo: some internal error, gateway timeout, etc.

Okay, which code should a Service Worker use when it itself fails?


· · Web · 2 · 4 · 6

Service Worker is a piece of JavaScript code that is acting effectively as a proxy, running in the user's browser but basically sitting between a website that registered it with the user's browser, and the client-side that the user controls and interacts with directly.

A fetch() in a Service Worker can fail for reasons related to the server — actual 4xx or 5xx errors issued by the server it is fetching data from. In such a case, easy, pass on the code received from the server.



…what if the Service Worker *itself* failed for some reason that is *not* related to the server it is fetching content from?

Say, there's a bug somewhere in the code of the Service Worker itself. And let's assume that this particular buggy code happens to be wrapped in a nice try-catch block.

The Service Worker can and should issue some kind of an error code to the user — otherwise the browser will display a generic "Site cannot be reached" message. Not very useful, that!

4xx? 5xx?


Service Worker is running in the client itself, in a very meaningful way it is *part* of the client. So maybe it should be a "client error" (4xx) type code?

But those codes are used for the *server* to tell the *client* it did something wrong. In our case, the server was never even contacted perhaps (say, the bug kicked in before an actual request got issued). This would make it as if the client telling itself it did something wrong.

Doesn't sound right.


Perhaps a 5xx, then? The Service Worker is effectively acting as a proxy or a gateway, getting requests from the client-side, processing them, and then issuing requests to the back-end, after all.

But again, when we see a 5xx error, we think: browser talked to the server, the server said crapped-out.

Here, the browser did not even get to talk to the server in the first place. On the most basic level, this is not a *server error*.

So, what should the Service Worker do?


I don't have an answer.

Perhaps we need to work out a standard here? Perhaps we should just agree to use some new, not-yet-assigned 4xx or 5xx code and call it a day?

But more and more sites are using the Service Workers API; my little side project — — also relies on it.

And currently when a Service Worker fails, the user (and the webdeveloper debugging their site!) get a pretty useless error message.

Suggestions welcome. 🙂


@rysiek my first inclination is to send a 5xx, just like a proxy on the other side of a network boundary would, and include a suitable error message in the result page

@rysiek in general though structured errors would be, like, nice

for when there's multiple gateways involved which is every large site :D

@rysiek 502 and a json(?) response body with details?

@rysiek Maybe “424 Failed Dependency (WebDAV; RFC 4918)
The request failed because it depended on another request and that request failed”?

@rysiek Well, the server has to have been reached in all cases, because that's where the service worker would have got its code from. 😉 That doesn't make any service worker error a server error though, as otherwise all other frontend errors were, too.

But aren't we in the wrong domain for HTTP status codes anyway? Those are meant for client-server-communication, which is not what the interaction between the sw and the user is I think.

@Aarkon @rysiek

But aren’t we in the wrong domain for HTTP status codes anyway? Those are meant for client-server-communication,

… which didn’t take place here, indeed. Similar to what happens when a browser can’t resolve a domain name through DNS, there was no HTTP involved, so a HTTP status code is probably not even the right direction!

@max @rysiek I think that if a domain can't be resolved, I see the browser's own error page for that, not a 404. 🤔
That is something we see when we e.g. ask a web server (that we already have a route to) for something that's not there. Similar, but different.

@max @Aarkon I would say HTTP was involved, as a fetch() happened. It was just (mis)handled by the Service Worker, not by the server.

@Aarkon the server must have had been reached once in the past.

Yeah, "wrong domain" is an interesting take. But if we're not to rely on HTTP codes, how should a Service Worker display an error to the user, then?

I am talking of a situation where there is no code available client-side yet. Service Worker had been cached and registered a while ago, the user navigates to the website. Service Worker handles the fetch() but errors-out. What should it return in the Response?

@rysiek why use a numbered error code within a service worker? it’s local to the user anyways. for a web worker it might make sense to use 400, but a service worker wouldn’t even be accessible on the internet

@rysiek Cloudflare uses custom 10xxx error codes for some problems. Yes, they are nonstandard, but your setup seems like that as well and it makes it easy to find the error code description when throwing it into a search engine.

My opinion is that it should return a 5xx as a way to tell the client they did not do anything wrong. If the client is a user-operated web browser there is not much to do about it, but if the client is a library it tells the programmer that the error is not their fault (i.e. packets are not malformed nor data missing and so).

Good question, anyhow.
Sign in to participate in the conversation
Mastodon for Tech Folks

mastodon.technology is shutting down by the end of 2022. Please migrate your data immediately. This Mastodon instance is for people interested in technology. Discussions aren't limited to technology, because tech folks shouldn't be limited to technology either!