Xabaril / AspNetCore.Diagnostics.HealthChecks

Enterprise HealthChecks for ASP.NET Core Diagnostics Package
Apache License 2.0
4.12k stars 800 forks source link

AspNetCore.HealthChecks.Publisher.Seq 8.0.1 fails to handle thrown exceptions #2251

Open calumriverscrezco opened 5 months ago

calumriverscrezco commented 5 months ago

What happened: Seq threw an exception

Health check HealthChecks.Publisher.Seq.SeqPublisher threw an unhandled exception after 12.1118ms
System.NotSupportedException: Serialization and deserialization of 'System.Reflection.MethodBase' instances is not supported. Path: $.Entries.Exception.TargetSite.
 ---> System.NotSupportedException: Serialization and deserialization of 'System.Reflection.MethodBase' instances is not supported.
   at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter`1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
...
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& state, NotSupportedException ex)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Serialize(Utf8JsonWriter writer, T& rootValue, Object rootValueBoxed)
   at System.Text.Json.JsonSerializer.WriteString[TValue](TValue& value, JsonTypeInfo`1 jsonTypeInfo)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
   at HealthChecks.Publisher.Seq.SeqPublisher.PublishAsync(HealthReport report, CancellationToken cancellationToken) in /_/src/HealthChecks.Publisher.Seq/SeqPublisher.cs:line 39

What you expected to happen: No exception

How to reproduce it (as minimally and precisely as possible):

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        try {
            throw new Exception();
        } catch (Exception e)
        {
            Console.WriteLine(JsonSerializer.Serialize(e));
        }
    }
}

Source code sample: https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/4a49dfa83b0524661387c9ee7b9aeff120198c14/src/HealthChecks.Publisher.Seq/SeqPublisher.cs#L54

Anything else we need to know?: Seems this was swapped from Newtonsoft.Json where you could serialize a thrown exception a revert of this change should fix it

HealthReportEntry within HealthReport contains a reference to the raw exception so when JsonSerializer.Serialize(HealthReport) happens it explodes

The exception has to be thrown for this to happen or it wont be populated with a $.TargetSite

Note non thrown exceptions work

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        var e = new Exception();
        Console.WriteLine(JsonSerializer.Serialize(e));
    }
}

Environment: