[ad_1]
I began to put in writing this weblog submit, having totally forgotten that I already explored this actual subject again in 2020: A Nearer Glance At Error Dealing with Throughout Parallel Array Iteration. In an ironic coincidence, on the other hand, this seems to be a useful oversight since the error dealing with habits has modified in Lucee CFML since that submit; and, is now divergent from Adobe ColdFusion’s implementation. As such, although it’s kind of redundant, I feel it is nonetheless worthy of a handy guide a rough have a look at error dealing with throughout async iteration in ColdFusion – 2024 version!
Parallel iteration, in ColdFusion, supplies the power to execute .every()
, .map()
, and .filter out()
on a set the use of parallel threads. It is without doubt one of the many options that makes asynchronous paintings in ColdFusion fairly simple. And, for probably the most phase, Adobe and Lucee have attempted to strike a wholesome stability between offering robust equipment and growing guard rails that save you folks from capturing themselves within the foot.
However, it isn’t all the time transparent the place the ones guard rails exist; and, how they’ll manifest within the utility. If we now have ColdFusion code and it is lately executing parallel iteration, what occurs when one of the vital threads throws an error:
-
What occurs to different parallel threads which are lately executing?
-
What occurs to pending threads that experience but to be spawned?
-
What if two working threads every throw an error – the place to these mistakes get surfaced?
I will discover this in each Adobe ColdFusion 2023 and Lucee CFML 6, that are the most recent variations of every CFML engine on the time of this writing (head nod to CommandBox for making this really easy to do). I will iterate asynchronously over an array the use of N/2
threads; and, I will throw an error within the first two threads.
Word: I’ve an Adobe ColdFusion (ACF) and Lucee CFML model of this code. Within the ACF model, I mock out the
sell off()
andsystemOutput()
purposes. For the sake of brevity, I am most effective going to turn the Lucee model.
Within the following code, word that I’ve a sleep(1000)
on the height of every iteration. This blocks every thread lengthy sufficient to make sure that ColdFusion has enough time to spawn the utmost choice of parallel threads (N/2
) prior to any error is thrown.
<cfscript>
values = [ "a", "b", "c", "d", "e", "f", "g", "h" ];
take a look at {
systemOutput( "#server.coldfusion.productName# - #server.lucee.model#", true );
systemOutput( "Values: #values.len()#", true );
// We are going to use parallel iteration to traverse the values array. And, we are
// going to THROW AN ERROR within the first TWO price. We need to see how those mistakes
// impact different threads already in procedure in addition to values left to discover.
values.every(
( price, index ) => {
systemOutput( "Getting into thread (#index#)", true );
sleep( 1000 );
// Throw an error in first two threads.
if ( index == 1 || index == 2 ) {
systemOutput( "** BOOM (#index#) **", true );
throw( sort = "Growth.#index#" );
}
sleep( 1000 );
systemOutput( "Exiting thread (#index#)", true );
},
true, // Parallel iteration.
( values.len() / 2 ) // Parallel thread depend.
);
} catch ( any error ) {
sell off( error );
}
</cfscript>
If we run this Lucee CFML 6 code and watch the server logs, here is what we see:

On this Lucee CFML 6 output, there are a number of necessary take-aways:
-
Any already-running parallel thread (within the asynchronous iteration) is authorized to finish even if any other thread throws an error. As proof of this, we will be able to see that threads
3
and4
go out effectively. -
Any pending iterations for components later within the array by no means get started. As proof of this, we will be able to see that threads
7
and8
by no means display up within the logs. -
With the exception that any thread in an instant following a crashed thread is authorized to begin. As proof of this, we will be able to see that thread
5
is in an instant spawned after the mistake in thread1
; and, we will be able to see that thread6
is in an instant spawned after the mistake in thread2
. Word that that is prior to threads3
and4
have completed.
Adequate, now let’s execute the similar CFML in Adobe ColdFusion 2023:

On this Adobe ColdFusion 2023 output, we will be able to see that all threads had been allowed to execute even after the 2 mistakes had been thrown.
That is what Lucee CFML 5.3 used to do, as in step with my submit from 2020. As such, Lucee CFML 6 (or previous) both has a regression. Or, it was once an intentional exchange made in the future via the Lucee group. I will attempt to see if I will determine that out and depart a remark.
This wasn’t illustrated within the terminal output; however, in each circumstances (Adobe ColFusion and Lucee CFML), most effective the primary thrown error, BOOM.1
, is surfaced within the top-level web page (by way of the take a look at/catch
). The second one error, BOOM.2
, fails silently within the background (and is probably logged to an error log someplace).
To be truthful, each behaviors make sense to me. At the one hand, I will see why you would need all the assortment to be iterated prior to an error is surfaced. However, however, I will completely perceive in need of to short-circuit the iteration when an error is encountered. As such, neither means is clearly proper or unsuitable in my eyes.
The lesson discovered here’s that you just must most certainly check your present CFML runtime to look the way it behaves throughout asynchronous iteration. And, possibly even higher, construct error dealing with into your async iteration in order that each the satisfied paths and unhappy paths are accounted for.
Need to use code from this submit?
Take a look at the license.
[ad_2]