Inside a loop, if a try/catch contains both a continue and a break, executing the continue leaves the loop, as a break would.
- The
breakdoesn’t need to run: its presence anywhere in thattry/catchis enough. - Positions measured:
continuein thetrywithbreakin thecatch, and both in thecatch. - Without the
break,continuebehaves correctly.
There’s no error, so this is silent wrong control flow. We found it as a lost iteration in a batch loop: after one item hit the skip path, the remaining items weren’t processed.
Repro
Standalone, no framework needed. Expected output on every line: a,b,c.
<cfscript>
// Standalone repro: no framework needed. Expected output on every line: a,b,c
function tryContinueCatchBreak() {
var trace = "";
for (var item in ["a", "b", "c"]) {
trace = ListAppend(trace, item);
try {
if (true) {
continue;
}
} catch (any e) {
break;
}
}
return trace;
}
function indexLoop() {
var trace = "";
var items = ["a", "b", "c"];
for (var i = 1; i <= 3; i++) {
trace = ListAppend(trace, items[i]);
try {
if (true) {
continue;
}
} catch (any e) {
break;
}
}
return trace;
}
function bothInCatch() {
var trace = "";
for (var item in ["a", "b", "c"]) {
trace = ListAppend(trace, item);
try {
throw(type = "probe", message = "x");
} catch (any e) {
if (true) {
continue;
}
break;
}
}
return trace;
}
function controlNoBreak() {
var trace = "";
for (var item in ["a", "b", "c"]) {
trace = ListAppend(trace, item);
try {
if (true) {
continue;
}
} catch (any e) {
var x = 1;
}
}
return trace;
}
writeOutput("engine: " & server.coldfusion.productname & " " & (server.lucee.version ?: server.coldfusion.productversion) & chr(10));
writeOutput("1 for-in, continue in try, break in catch : " & tryContinueCatchBreak() & chr(10));
writeOutput("2 index loop, same : " & indexLoop() & chr(10));
writeOutput("3 continue and break both in catch : " & bothInCatch() & chr(10));
writeOutput("4 control: no break in the try/catch : " & controlNoBreak() & chr(10));
</cfscript>
Output on Lucee 7.0.0.395:
1 for-in, continue in try, break in catch : a
2 index loop, same : a
3 continue and break both in catch : a
4 control: no break in the try/catch : a,b,c
Measured builds
| Engine | Result |
|---|---|
| Lucee 6.2.5.48 | wrong (continue exits the loop) |
| Lucee 7.0.1.100 | wrong |
| Lucee 7.0.0.395 | wrong |
| Adobe ColdFusion 2023.0.11 / 2025.0.06 | correct (a,b,c) |
| BoxLang 1.11.0+52 | correct |
How each was measured:
- 6.2.5.48 and 7.0.1.100: an equivalent TestBox probe (same shapes) in CI containers.
- 7.0.0.395: that probe and the standalone repro above.
Also correct on every engine measured:
- a loop nested inside a
trythat usescontinueandbreakfor that loop; - the same
try/catchwithout thebreak.
The failing shape reproduces with for-in and index loops, with or without an outer try/finally.
Workaround
Avoid continue in such a try/catch; carry control to the end of the iteration with if/else.
I don’t have a Lucee Jira account. Could a Lucee maintainer open an LDEV issue for this? Thanks!