fix(site-runtime): step-log review — trace-flag-gated ES step scope, shared-script Log, formatter guard
Task 5 code-review follow-ups: - I1: ExternalSystemHelper gates its TraceStepScope on a new isTraced ctor arg (default false for direct construction), not on `_traceSink is not null` — a traced run without an inline collector still writes durable ScriptLog rows that must name their step. - I2 (design §5): an inline shared script now SHARES its caller's ScriptLogger via the new `sharedLog` ctor param — one line cap, one anchor, one closing row. Consequence documented on the Log property: a shared script's lines carry the PARENT run's ExecutionId and land on the parent's ScriptRun node. - M3: TraceCapturingLogger swallows a throwing formatter — most of what it captures is best-effort "audit write failed" warnings logged from inside a catch block, and a formatting exception must not escape that path. - Tests: ApiCall step attribution, traced-without-collector, shared-script logger sharing, nested batch/wait scope attribution + unwind, throwing formatter; test (c) now also pins the anti-recursion property (EmitLog must log through the undecorated logger). CompileSurfaceParityTests stays red until Task 7 mirrors Log on ScriptCompileSurface.
This commit is contained in:
@@ -156,6 +156,27 @@ public class TraceCapturingLoggerTests
|
||||
Assert.Throws<ArgumentNullException>(() => new TraceCapturingLogger(new RecordingLogger(), null!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AThrowingFormatter_IsSwallowed_AndDropsOnlyThatLine()
|
||||
{
|
||||
// Review M3. Most of what this decorator captures is the runtime's own best-effort
|
||||
// "audit write failed" warnings, logged from INSIDE a catch block: a formatter exception
|
||||
// escaping here would replace the original failure with a formatting one on a path whose
|
||||
// contract is that it never throws. The inner logger is disabled for this level so the
|
||||
// decorator's OWN formatter call is the only one under test.
|
||||
var (logger, inner, rows) = Make(innerMinimum: LogLevel.Critical);
|
||||
|
||||
logger.Log(LogLevel.Warning, new EventId(0), "state", null,
|
||||
(_, _) => throw new InvalidOperationException("formatter broke"));
|
||||
|
||||
Assert.Empty(rows);
|
||||
Assert.Empty(inner.Entries);
|
||||
|
||||
// …and the decorator keeps working for the next line.
|
||||
logger.LogWarning("still alive");
|
||||
Assert.Equal("still alive", Assert.Single(rows).Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BeginScope_DelegatesToTheInnerLogger()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user