Workflow Loop block dont abort on individual failed iteration

Hey there! Love retool. Have a very small question that hopefully is not a big ask.

I have a workflow that iterates over a loop using a loop block and for every record in the array, it calls a second workflow. (I have a lot of steps with each record). On some records the sub workflow fails. I am having a difficult time configuring it so that the loop will continue even if one of the sub workflows fail. I set finally->continue but it still seems to abort the entire loop. Any ideas?

I haven't tested this, but what if you go to the failure point in the subworkflow and set that block to finally continue. Then connect a javascript code block off the red failure pin and try and return a fake succesful JSON object? Or maybe you can perform a secondary action such as updating the postrgresql record to show that the record failed but that step being successful would allow it to proceed with the rest of the loop?

1 Like

I got it eventually! The trick was to write custom loop iteration code rather than their preset GUI looping construct and simple wrap the line where it iterates over iterations of the lambda in a try catch :slight_smile:

2 Likes

Nice, thanks for sharing back your solution here @Bill_Boulden ! This could very well help a ton of others trying to do something similar :rocket: So much is possible by writing a bit of custom code in your workflow blocks :star_struck: And thanks for chiming in with ideas too @nhilbelink !

Confirming the solution @Bill_Boulden posted is probably the best practice here. I took a look at this with a teammate on our support eng team -- for any non standard loop behavior, you'll have to add the functionality in yourself, or manage your own behavior in a JS block (which is how we prefer to do it). Just in case other folks stumble across this in the future, I'll share some code to demonstrate this a bit.

The solution we tested for this is as follows (where query3 is a rest api query to trigger a different workflow):

The code for query3:

const results = [];

for (const [index, value] of code1.data.entries()) {
  try {
    const result = await query3_lambda.trigger();
    results.push(result);
  } catch (error) {
    results.push(""); // Indicate error occurred
  }
}
return await Promise.all(results);

versus the original loop code:

const results = [];
  for (const [index, value] of code1.data.entries()) {
    const result = await query3_lambda.trigger();
    results.push(result);
  }
return await Promise.all(results)

For reference, the other workflow that query 3 triggers is: