From 32b658fe717952197fef6da4d3a85f099fb63f79 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Tue, 3 Nov 2026 22:57:03 -0500 Subject: [PATCH] perf(engine): list a few step names in a missing-reference error (#1941) Every missing $ref rendered the batch's whole name table into its error, and with onError: continue each such error was kept, so a compact batch cost its name count per failed step. The hint names twelve steps and counts the rest. --- crates/engine/src/automation/batch.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/automation/batch.rs b/crates/engine/src/automation/batch.rs index 103177455..e0f22d870 100644 --- a/crates/engine/src/automation/batch.rs +++ b/crates/engine/src/automation/batch.rs @@ -156,14 +156,20 @@ impl BatchScope { lookup(result, path).cloned().map_err(|why| fail(format!("{who}'s result has no `{path}`{why}"))) } + /// Most step names a missing-reference error lists. + const NAME_HINTS: usize = 12; + fn known_names(&self) -> String { let mut names: Vec<_> = self.names.iter().collect(); names.sort_by_key(|(_, i)| **i); if names.is_empty() { return "no step has an `as` name".into(); } - let list: Vec<_> = names.iter().map(|(name, i)| format!("\"{name}\" is step {i}")).collect(); - list.join(", ") + // A few of them: the list is built for every missing reference and, with `onError: + // continue`, kept for each, so a long table would cost its length per failed step. + let list: Vec<_> = names.iter().take(Self::NAME_HINTS).map(|(name, i)| format!("\"{name}\" is step {i}")).collect(); + let more = names.len().saturating_sub(Self::NAME_HINTS); + if more > 0 { format!("{}, {more} more", list.join(", ")) } else { list.join(", ") } } }