fix(site-runtime): TraceCapturingLogger rejects double-wrapping; ScriptLogger clip keeps surrogate pairs (Task 4 review)
This commit is contained in:
@@ -165,7 +165,28 @@ public sealed class ScriptLogger
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Applies the per-message cap, marking a truncated message with a trailing ellipsis.</summary>
|
||||
private static string Clip(string? m) =>
|
||||
m is null ? string.Empty : m.Length <= MaxMessageChars ? m : m[..MaxMessageChars] + "…";
|
||||
/// <summary>
|
||||
/// Applies the per-message cap, marking a truncated message with a trailing ellipsis.
|
||||
///
|
||||
/// <para>Cuts one char short when the cap would land between the two halves of a surrogate
|
||||
/// pair, so an emoji straddling the boundary is dropped whole rather than leaving a lone
|
||||
/// surrogate that breaks JSON serialization downstream. Re-clipping an already-clipped message
|
||||
/// is a no-op, which matters because the script path clips once before logging and again
|
||||
/// before emitting.</para>
|
||||
/// </summary>
|
||||
private static string Clip(string? m)
|
||||
{
|
||||
if (m is null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (m.Length <= MaxMessageChars)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
|
||||
var keep = char.IsHighSurrogate(m[MaxMessageChars - 1]) ? MaxMessageChars - 1 : MaxMessageChars;
|
||||
return m[..keep] + "…";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user