Skip to content

Commit ec5d23a

Browse files
committed
refactor and more test coverage
1 parent d28feb4 commit ec5d23a

File tree

3 files changed

+386
-11
lines changed

3 files changed

+386
-11
lines changed

libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ public void EndSubsegment()
137137
catch (Exception e) when (IsSerializationError(e))
138138
{
139139
// This is a JSON serialization error - handle it aggressively
140-
Console.WriteLine("JSON serialization error detected in Tracing utility - attempting recovery");
141140
Console.WriteLine($"Error: {e.Message}");
142141

143142
HandleSerializationError(e);
@@ -191,16 +190,12 @@ private void HandleSerializationError(Exception originalException)
191190
try
192191
{
193192
// Strategy 1: Try to clear and recreate with minimal data
194-
Console.WriteLine("Attempting serialization error recovery - Strategy 1: Clear and recreate");
195-
196193
_awsxRayRecorder.TraceContext.ClearEntity();
197194
_awsxRayRecorder.BeginSubsegment("Tracing_Sanitized");
198195
_awsxRayRecorder.AddAnnotation("SerializationError", true);
199196
_awsxRayRecorder.AddMetadata("Error", "Type", "JSON Serialization Error");
200197
_awsxRayRecorder.AddMetadata("Error", "Message", SanitizeValueForMetadata(originalException.Message));
201198
_awsxRayRecorder.EndSubsegment();
202-
203-
Console.WriteLine("Serialization error recovery successful");
204199
}
205200
catch (Exception e2)
206201
{
@@ -213,8 +208,6 @@ private void HandleSerializationError(Exception originalException)
213208
_awsxRayRecorder.BeginSubsegment("Tracing_Error");
214209
_awsxRayRecorder.AddAnnotation("Error", "SerializationFailed");
215210
_awsxRayRecorder.EndSubsegment();
216-
217-
Console.WriteLine("Minimal serialization error recovery successful");
218211
}
219212
catch (Exception e3)
220213
{
@@ -388,7 +381,7 @@ private static object SanitizeValueRecursive(object value, int depth)
388381
return collectionResult;
389382

390383
// Handle complex objects
391-
return SanitizeComplexObject(value, type, depth);
384+
return SanitizeComplexObject(value, type);
392385
}
393386

394387
/// <summary>
@@ -557,13 +550,11 @@ private static object SanitizeEnumerable(System.Collections.IEnumerable enumerab
557550
/// </summary>
558551
/// <param name="value">The object to sanitize</param>
559552
/// <param name="type">The object type</param>
560-
/// <param name="depth">Current recursion depth</param>
561553
/// <returns>Sanitized string representation</returns>
562-
private static object SanitizeComplexObject(object value, Type type, int depth)
554+
private static object SanitizeComplexObject(object value, Type type)
563555
{
564556
try
565557
{
566-
// For Native AOT compatibility, we avoid reflection and convert to string
567558
// This ensures the object can be serialized without issues
568559
return $"[{type.Name}] {value.ToString()}";
569560
}

libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/EntityLevelSanitizationTests.cs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,132 @@ public void SanitizeCurrentEntitySafely_WithComplexProblematicData_HandlesAllSce
153153
Assert.Fail($"EndSubsegment with null entity should not throw: {ex.Message}");
154154
}
155155
}
156+
157+
[Fact]
158+
public void SanitizeCurrentEntitySafely_WithProblematicData_SanitizesSuccessfully()
159+
{
160+
// Arrange
161+
var mockAwsXRayRecorder = Substitute.For<IAWSXRayRecorder>();
162+
var mockConfigurations = Substitute.For<IPowertoolsConfigurations>();
163+
mockConfigurations.IsLambdaEnvironment.Returns(true);
164+
165+
// Create a real subsegment to test actual sanitization
166+
var subsegment = new Subsegment("TestSegment");
167+
168+
// Add problematic data to the subsegment (only metadata, not annotations with DateTime)
169+
subsegment.AddMetadata("test", "problematic_ulong", 42ul);
170+
subsegment.AddMetadata("test", "problematic_guid", Guid.NewGuid());
171+
subsegment.AddMetadata("test", "problematic_datetime", DateTime.Now);
172+
subsegment.AddAnnotation("safe_annotation", "safe_value");
173+
174+
var mockTraceContext = Substitute.For<Amazon.XRay.Recorder.Core.Internal.Context.ITraceContext>();
175+
mockTraceContext.GetEntity().Returns(subsegment);
176+
mockAwsXRayRecorder.TraceContext.Returns(mockTraceContext);
177+
178+
var recorder = new XRayRecorder(mockAwsXRayRecorder, mockConfigurations);
179+
180+
// Act & Assert - Should not throw
181+
try
182+
{
183+
recorder.EndSubsegment();
184+
185+
// Verify that EndSubsegment was called
186+
mockAwsXRayRecorder.Received(1).EndSubsegment();
187+
}
188+
catch (Exception ex)
189+
{
190+
Assert.Fail($"EndSubsegment with problematic data should not throw: {ex.Message}");
191+
}
192+
}
193+
194+
[Fact]
195+
public void SanitizeEntityMetadata_WithReflectionFailure_HandlesGracefully()
196+
{
197+
// Arrange
198+
var mockAwsXRayRecorder = Substitute.For<IAWSXRayRecorder>();
199+
var mockConfigurations = Substitute.For<IPowertoolsConfigurations>();
200+
mockConfigurations.IsLambdaEnvironment.Returns(true);
201+
202+
// Create a subsegment and make GetEntity throw an exception to simulate reflection failure
203+
var mockTraceContext = Substitute.For<Amazon.XRay.Recorder.Core.Internal.Context.ITraceContext>();
204+
mockTraceContext.GetEntity().Returns(x => throw new Exception("Reflection error"));
205+
mockAwsXRayRecorder.TraceContext.Returns(mockTraceContext);
206+
207+
var recorder = new XRayRecorder(mockAwsXRayRecorder, mockConfigurations);
208+
209+
// Act & Assert - Should not throw
210+
try
211+
{
212+
recorder.EndSubsegment();
213+
214+
// Verify that EndSubsegment was still called despite the reflection error
215+
mockAwsXRayRecorder.Received(1).EndSubsegment();
216+
}
217+
catch (Exception ex)
218+
{
219+
Assert.Fail($"EndSubsegment with reflection failure should not throw: {ex.Message}");
220+
}
221+
}
222+
223+
[Fact]
224+
public void SanitizeEntityAnnotations_WithNullAnnotations_HandlesGracefully()
225+
{
226+
// Arrange
227+
var mockAwsXRayRecorder = Substitute.For<IAWSXRayRecorder>();
228+
var mockConfigurations = Substitute.For<IPowertoolsConfigurations>();
229+
mockConfigurations.IsLambdaEnvironment.Returns(true);
230+
231+
// Create a subsegment with null annotations property (simulated)
232+
var subsegment = new Subsegment("TestSegment");
233+
234+
var mockTraceContext = Substitute.For<Amazon.XRay.Recorder.Core.Internal.Context.ITraceContext>();
235+
mockTraceContext.GetEntity().Returns(subsegment);
236+
mockAwsXRayRecorder.TraceContext.Returns(mockTraceContext);
237+
238+
var recorder = new XRayRecorder(mockAwsXRayRecorder, mockConfigurations);
239+
240+
// Act & Assert - Should not throw
241+
try
242+
{
243+
recorder.EndSubsegment();
244+
245+
// Verify that EndSubsegment was called
246+
mockAwsXRayRecorder.Received(1).EndSubsegment();
247+
}
248+
catch (Exception ex)
249+
{
250+
Assert.Fail($"EndSubsegment with null annotations should not throw: {ex.Message}");
251+
}
252+
}
253+
254+
[Fact]
255+
public void SanitizeEntityHttpInformation_WithNullHttp_HandlesGracefully()
256+
{
257+
// Arrange
258+
var mockAwsXRayRecorder = Substitute.For<IAWSXRayRecorder>();
259+
var mockConfigurations = Substitute.For<IPowertoolsConfigurations>();
260+
mockConfigurations.IsLambdaEnvironment.Returns(true);
261+
262+
// Create a subsegment with null HTTP property (simulated)
263+
var subsegment = new Subsegment("TestSegment");
264+
265+
var mockTraceContext = Substitute.For<Amazon.XRay.Recorder.Core.Internal.Context.ITraceContext>();
266+
mockTraceContext.GetEntity().Returns(subsegment);
267+
mockAwsXRayRecorder.TraceContext.Returns(mockTraceContext);
268+
269+
var recorder = new XRayRecorder(mockAwsXRayRecorder, mockConfigurations);
270+
271+
// Act & Assert - Should not throw
272+
try
273+
{
274+
recorder.EndSubsegment();
275+
276+
// Verify that EndSubsegment was called
277+
mockAwsXRayRecorder.Received(1).EndSubsegment();
278+
}
279+
catch (Exception ex)
280+
{
281+
Assert.Fail($"EndSubsegment with null HTTP info should not throw: {ex.Message}");
282+
}
283+
}
156284
}

0 commit comments

Comments
 (0)