event.waitUntil isn't really waiting

#1

I have an async function that looks like this:

    export async function record(data) {
      sentryLog({message: 'started logging'});
      const response = await putItem(data);
      sentryLog({message: 'done'});
    }

I don’t want my worker to wait for the call to finish before returning to the client and so I call it using event.waitUntil like this:

    event.waitUntil(record({foo: 'bar'}));

The function ‘sentryLog’ is just a helper function that I wrote so that I could get some log data when the function is called outside the Cloudflare editor. I’ve found that when I am inside the Cloudflare editor everything works fine - I get both of the log messages. Also, If I don’t use event.waitUntil and I just wait for the async call to finish everything works fine. However, after deploying the code I get the first log message but I never get the second log message. The putItem calls dynamodDB and I never get a new entry. Anyone know what’s up with waitUntil? It appears to not actually wait but instead once I’ve returned from my handler I think Cloudflare is killing my process.

Thanks!

0 Likes

#2

Do you return after the event.waitUntil?

event.waitUntil(record({foo: 'bar'}));
return response

For logging see this example:

0 Likes

#3

Thanks for the sample code. I should have included more of my code. I do return the response from the putItem call like this:

export async function record(data) {
      sentryLog({message: 'started logging'});
      const response = await putItem(data);
      sentryLog({message: 'done'});
      return response;
}

The calling code looks like this:

function handleRequest(event) {
    record(data);
    const url = ''https://www.example.com;
    try {
         return Response.redirect(url, status);
    } catch(err) {
        sentryLog(err);
        return new Response("There was an error: " + err);
    }
}

And then addEventListener

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event));
});

I don’t end up needing to make a remote request via fetch. I am able to use the ‘Response’ object and return immediately. Maybe that’s why the waitUntil appears to be ignored?

0 Likes

#4

In the last post you don’t have any event.waitUntil. Could you clarify where you call event.waitUntil?

Also, could you clarify what your goal is? record returns a response, but you never use that response. And what does sentryLog do? Log to sentry (HTTP requests)?

Assuming they make subrequests to Sentry, since you don’t await the sentryLog calls, and don’t pass them to event.waitUntil, they are likely to be cancelled by Cloudflare.

Anything that returns a Promise and that is not awaited or thened has to be passed to event.waitUntil or risk being cancelled when you return the response to Cloudflare.

0 Likes

#5

Sorry I mean for record to be wrapped in the waitUntil. The returned response was another artifact of playing around with the code to see what I could get working. The sentryLog is only there because once deployed I have no other way of logging so for now I’m just sending errors to Sentry so I can see what’s going on inside the code. My assumption is that since record is an sync function event.waitUntil will treat it the same as a promise and allow it to finish even after I’ve returned a response from handleRequest to event.respondWith.

I’ve included the updated code below:

export async function record(data) {
      sentryLog({message: 'started logging'});
      const response = await putItem(data);
      sentryLog({message: 'done'});
}

function handleRequest(event) {
    event.waitUntil(record(data));
    const url = ''https://www.example.com;
    try {
         return Response.redirect(url, status);
    } catch(err) {
        sentryLog(err);
        return new Response("There was an error: " + err);
    }
}

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event));
});
0 Likes

#6

Thanks to @adaptive I switched over to logdna to handle my logging which is much nicer than using Sentry for logging. That enabled me to realize that everything in the Cloudflare worker was working fine. I was doing a redirect which the browser cached. The worker was being called on the first request and the event.waitUntil was working just fine on the first request. After that the browser doesn’t bother making the request to get the redirect it just loads the url to which it was previously redirected.

1 Like