@@ -5,6 +5,8 @@ namespace Sentry;
55/// </summary>
66internal class W3CTraceHeader
77{
8+ private const string SupportedVersion = "00" ;
9+
810 /// <summary>
911 /// The name of the W3C trace context header used for distributed tracing.
1012 /// This field contains the value "traceparent" which is part of the W3C Trace Context specification.
@@ -18,7 +20,10 @@ internal class W3CTraceHeader
1820 /// <exception cref="ArgumentNullException">Thrown when <paramref name="source"/> is null.</exception>
1921 public W3CTraceHeader ( SentryTraceHeader source )
2022 {
21- ArgumentNullException . ThrowIfNull ( source ) ;
23+ if ( source is null )
24+ {
25+ throw new ArgumentNullException ( nameof ( source ) , "Source Sentry trace header cannot be null." ) ;
26+ }
2227
2328 SentryTraceHeader = source ;
2429 }
@@ -31,17 +36,58 @@ public W3CTraceHeader(SentryTraceHeader source)
3136 /// </value>
3237 public SentryTraceHeader SentryTraceHeader { get ; }
3338
39+ /// <summary>
40+ /// Parses a <see cref="SentryTraceHeader"/> from a string representation of the Sentry trace header.
41+ /// </summary>
42+ /// <param name="value">
43+ /// A string containing the Sentry trace header, expected to follow the format "traceId-spanId-sampled",
44+ /// where "sampled" is optional.
45+ /// </param>
46+ /// <returns>
47+ /// A <see cref="SentryTraceHeader"/> object if parsing succeeds, or <c>null</c> if the input string is null, empty, or whitespace.
48+ /// </returns>
49+ /// <exception cref="FormatException">
50+ /// Thrown if the input string does not contain a valid trace header format, specifically if it lacks required trace ID and span ID components.
51+ /// </exception>
52+ public static W3CTraceHeader ? Parse ( string value )
53+ {
54+ if ( string . IsNullOrWhiteSpace ( value ) )
55+ {
56+ return null ;
57+ }
58+
59+ var components = value . Split ( '-' , StringSplitOptions . RemoveEmptyEntries ) ;
60+ if ( components . Length < 2 )
61+ {
62+ throw new FormatException ( $ "Invalid W3C trace header: { value } .") ;
63+ }
64+
65+ var version = components [ 0 ] ;
66+ if ( version != SupportedVersion )
67+ {
68+ throw new FormatException ( $ "Invalid W3C trace header version: { version } .") ;
69+ }
70+
71+ var traceId = SentryId . Parse ( components [ 1 ] ) ;
72+ var spanId = SpanId . Parse ( components [ 2 ] ) ;
73+
74+ var isSampled = components . Length >= 4
75+ ? string . Equals ( components [ 3 ] , "01" , StringComparison . OrdinalIgnoreCase )
76+ : ( bool ? ) null ;
77+
78+ return new W3CTraceHeader ( new SentryTraceHeader ( traceId , spanId , isSampled ) ) ;
79+ }
80+
3481 /// <inheritdoc/>
3582 public override string ToString ( )
3683 {
37- const string version = "00" ;
3884 var traceFlags = ConvertSampledToTraceFlags ( SentryTraceHeader . IsSampled ) ;
3985 if ( traceFlags is null )
4086 {
41- return $ "{ version } -{ SentryTraceHeader . TraceId } -{ SentryTraceHeader . SpanId } ";
87+ return $ "{ SupportedVersion } -{ SentryTraceHeader . TraceId } -{ SentryTraceHeader . SpanId } ";
4288 }
4389
44- return $ "{ version } -{ SentryTraceHeader . TraceId } -{ SentryTraceHeader . SpanId } -{ traceFlags } ";
90+ return $ "{ SupportedVersion } -{ SentryTraceHeader . TraceId } -{ SentryTraceHeader . SpanId } -{ traceFlags } ";
4591 }
4692
4793 /// <inheritdoc/>
0 commit comments