How to catch/handle cancelled requests

What is the lifecycle of a cancelled request?

If a request reaches a worker and the client subsequently disconnects before the worker finishes returning a response, the request shows up in the logs with a status of “cancelled”.

I gather from various comments that the Workers runtime would cancel all processes related to the request when the client disconnects, and but there may be a window of up to 30s afforded for promises to resolve if they are passed to ctx.waitUntil()?

What is the recommended way to catch the cancellation of a request so that it can be logged to a third-party logging agent?

What happens when a client disconnects while a sub-request is in flight before the worker returns a Response?

Does the fetch() reject with an error or does the process just end and never return? Is there a way to “catch” the cancellation so the request can finally be logged?

What happens when a client disconnects after the Response is returned but before the body stream has completed sending?

I gather from another thread that the body stream could be piped through an IdentityTransformStream and that the promise returned by stream.pipeTo() should reject when the client disconnects, and this could be caught and logged so long as the promise is passed to ctx.waitUntil().

Are promises passed to ctx.waitUntil() allowed to resolve after a request is cancelled?

I have all these things set up, including an overall try/catch, and ctx.waitUntil() to log the request to a third-party API. But when a request is cancelled nothing is logged, seemingly like everything is immediately aborted in flight.

Thus I am left wondering.

6 Likes

Have you ever found a solution?

request.signal seems like a step in the right direction, e.g.

request.signal.addEventListener('abort', () => {
  console.log('client disconnected');
});

But I couldn’t get it triggered (or, at least, couldn’t see the “client disconnected” message in the logs).

Nah, I find that ctx.waitUntil() is the only reliable way to keep the “thread” alive for a short period of time. But there remains no way to know when a request has been aborted/cancelled by the client.

Yeah Request.signal would be a convenient API for Cloudlfare to utilise to notify client disconnect. But like you say I doubt they implement it. Great idea for a feature request :wink: .