< Summary - AsyncResponse (Release / net8.0+net10.0 / unit+integration)

Information
Class: AsyncResponse.RemoteStackTrace
Assembly: AsyncResponse.Core
File(s): /_/src/AsyncResponse.Core/RemoteStackTrace.cs
Line coverage
100%
Covered lines: 6
Uncovered lines: 0
Coverable lines: 6
Total lines: 38
Line coverage: 100%
Branch coverage
100%
Covered branches: 10
Total branches: 10
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ForWire(...)100%22100%
Cap(...)100%88100%

File(s)

/_/src/AsyncResponse.Core/RemoteStackTrace.cs

#LineLine coverage
 1namespace AsyncResponse;
 2
 3/// <summary>
 4/// Applies the wire policy for a remote exception stack trace shared across the durable channels:
 5/// whether it travels on the wire at all, and a hard length cap so a buggy or hostile remote cannot
 6/// push a multi-megabyte trace into the envelope (and from there into generic exception logs).
 7/// </summary>
 8internal static class RemoteStackTrace
 9{
 10    private const string TruncationMarker = "… [stack trace truncated by AsyncResponse]";
 11
 12    /// <summary>
 13    /// The publish-side policy: returns <c>null</c> when <paramref name="include"/> is <c>false</c>,
 14    /// otherwise the trace capped to <paramref name="maxLength"/>.
 15    /// </summary>
 16    public static string? ForWire(string? stackTrace, bool include, int maxLength)
 9617        => include ? Cap(stackTrace, maxLength) : null;
 18
 19    /// <summary>
 20    /// Truncates <paramref name="stackTrace"/> to <paramref name="maxLength"/> characters, appending a
 21    /// marker when truncated. Used on both publish (bound what we emit) and receive (bound what we
 22    /// accept from a remote we do not control). A non-positive cap leaves the input unchanged so a
 23    /// misconfiguration cannot silently erase diagnostics.
 24    /// </summary>
 25    public static string? Cap(string? stackTrace, int maxLength)
 26    {
 11527        if (string.IsNullOrEmpty(stackTrace) || maxLength <= 0 || stackTrace.Length <= maxLength)
 10728            return stackTrace;
 29
 30        // Never split a surrogate pair at the cap: an unpaired high surrogate is ill-formed UTF-16,
 31        // which every framework UTF-8 encoder silently replaces with U+FFFD on the wire instead of
 32        // failing — back off to the last whole code point.
 833        if (char.IsHighSurrogate(stackTrace[maxLength - 1]))
 234            maxLength--;
 35
 836        return string.Concat(stackTrace.AsSpan(0, maxLength), TruncationMarker);
 37    }
 38}