Query timeout not respeted on Javascript queries

Context: I use Javascript queries for complex logic of query interactions. Sometimes the child queries never resolve. That is a separate issue, which could be worked around by timeouts, which also didn't seem to work properly. In exploring I discovered that a Javascript query does not respect the timeout settings. This is pretty simple to reproduce in a Javascript query with Promise that will never resolve in time:

await (async function() {
  return new Promise((resolve => {
    window.setTimeout(() => { Promise.resolve(resolve)}, 999999)
  }));
})();

If you run or trigger this query in any way, one of two things should happen:

  • It hits the default 10 second timeout limit of the query
  • It hits the documented hard 120 second limit of a query

Neither of these happen, shown clearly that the query has run for over five minutes, which should be impossible

Hey @Rory!

Thanks for surfacing this, it's something our engineering team has been made aware of, I'll let you know here when a fix has been published :slightly_smiling_face:

Hello,

Has there been any progress on this issue in the last several months? I ran into the same issue on my company's on-prem version of retool.

Best,
Sam Shersher

Hey @sshersh, no updates yet unfortunately :pensive: but I've resurfaced it with the dev team. Is there a particular way that this is causing problems for you? Happy to help think of workarounds in the meantime!

In my case, I use Javascript queries as an entry point on which database query to run. For example, a drop down which control which query is the output for a table

const queries = {
  "Foo": FooQuery,
  "Bar": BarQuery,
  "Baz": BazQuery,
  "Frob": FrobQuery,
};

return queries[QueryControlDropdown.value].trigger();

If any one of the underlying queries times out, the javascript query will continue to run forever, forcing the user to hard refresh the page.
This is less of an issue now that there has been infrastructure improvements within Retool over the past year. However, it is still unexpected that setting a timeout on a javascript query does not actually work.

For now, you might try adding a wrapper in order to manually implement a timeout in your JS query, something like:

const timeout = 1000;
const timeoutMessage = `Query timed out after ${timeout / 1000} seconds`;

const timeoutPromise = new Promise((_, reject) =>
  setTimeout(() => reject(timeoutMessage), timeout)
);
const query = (async () => {
  /*
  
    paste your query code here
  

  */
})();

return Promise.race([timeoutPromise, query]);

@Rory are you still seeing your JavaScript queries run indefinitely if one of the underlying queries times out? If so, what kind of queries are they?

Edit: Note that the above code doesn't kill all processes at the timeout, it should just make the query return. It's more of a pseudo-timeout wrapper and infinite loops in your query's code, for example, will still run in the background which can impact performance if they're costly.

How best to timeout your JS query will depend on your particular use case!

Hello all, quick update here. For now, the timeout setting on JS queries has been disabled and the expected path is to include any timeout logic within the query itself. If you have any trouble setting things up, e.g. the snippet above doesn't work for you, please let us know!

The snippet above does not work for me. Yes, timeoutPromise is fulfilled, but my query keeps running. How do I stop the query from running without forcing the user to refresh the page as initially described?

Hey @Billy_Richmond!

Would you mind posting the full code from your query for comparison? Or so that we can try to reproduce the issue?

Yes, @Kabirdas, let me try to find it, and I will post it. Thanks.