Workaround for using Try/Catch Blocks with Queries Triggered by .trigger()

We have seen some users running into issues with this, and we do have a feature request to handle this natively, but in the meantime, here is a workaround.

Issue:

Currently, if a query is triggered using the trigger() method, it will resolve even if the triggered query fails, preventing the catch block from being run.

Workaround:

I found that if you wrap the trigger in another promise that rejects when the query has failed, then the try/catch blocks work!

Step 1: Create the wrapper function

function triggerWithCatch(query, additionalScope = {}) {
  return new Promise((resolve, reject) => {
    query.trigger({
      additionalScope,
      onSuccess: (data) => resolve(data),
      onFailure: (error) => {
        const message = typeof error === 'string' ? error : JSON.stringify(error);
        reject(new Error(message));
      }
    });
  });
}

*This function handles String and Object type errors

Step 2: Call the wrapper function in Try/Catch Blocks

try {
  const data = await triggerWithCatch(query19);
  console.log("Success:", data);
} catch (e) {
  const errorObjData = JSON.parse(e.message).data;
  console.error("Caught error:", errorObjData.message);
}

Simply pass the query name as an argument, and any additional scope, then let the wrapper take care of the rest!

*Error parsing can vary depending on how you want to use this data

Examples:

Successful query

Failed Query

6 Likes

Hi @cperea , any when the fix for this will be released? I have a query calling some other inner queries and adding this workaround would make it too verbose. Thanks!

Hey @marcus-santos-bold - we don't have a concrete timeline just yet!

I have a non-urgent question and a comment regarding this workaround…

The question:

const message = typeof error === 'string' ? error : JSON.stringify(error);

^^ In what scenarios would error not be a string? In my experience, this has always been a json string.

The comment:

If I call triggerWithCatch within triggerWithCatch, and an error is thrown in the second, it’s been my experience that the resulting error will contain something gnarly like

{"name":"QueryRunError","errorData":"{"name":"QueryRunError","errorData":"This is my original error message.","trigger":"NATURAL_FAILURE","displayOptions":{"hideToast":false},"lineNumber":104}","trigger":"NATURAL_FAILURE","displayOptions":{"hideToast":false}}

Notice how there is an errorData that has another error object (as a string) within it.

I addressed this by making the following change – radically candid feedback welcome

function triggerWithCatch = (query, additionalScope = {}) => {
  return new Promise((resolve, reject) => {
    query.trigger({
      additionalScope,
      onSuccess: (data) => resolve(data),
      onFailure: (queryError) => {
        let errorToThrow = null;
        if (typeof queryError === "string") {
          try {
            const errorAsObj = JSON.parse(queryError);
            errorToThrow = new Error(errorAsObj.errorData);
          } catch {
            errorToThrow = new Error(queryError);
          }
        } else if (queryError instanceof Error)
          // I don't think we'll ever get in here.
          errorToThrow = queryError;
        else
          // I don't think we'll ever get in here.
          errorToThrow = new Error(JSON.stringify(queryError));       
        reject(errorToThrow);
      }
    });
  });
}