in src/Activities/Internal/DiagnosticsListener/DiagnosticsObserversInitializer.cs [105:142]
private void OnException(string eventName, object? payload) =>
m_logger.LogError(
Tag.Create(),
ExtractExceptionFromPayload(payload),
"Exception diagnostic event '{0}' with payload '{1}'", eventName, payload);
// Made internal for unit testing
internal static Exception? ExtractExceptionFromPayload(object? payload)
{
if (payload == null)
{
return null;
}
else if (payload is Exception exception)
{
return exception;
}
else
{
// Attempting to find exception property since payload often use private classes,
// It would be completely removed after .NET 5 release.
// It's definitely not ideal identification
// DataAdapters doing it by parameter name https://github.com/aspnet/EventNotification/blob/28b77e7fb51b30797ce34adf86748c98c040985e/src/Microsoft.Extensions.DiagnosticAdapter/Internal/ProxyMethodEmitter.cs#L69
// Sample class with payload https://github.com/dotnet/runtime/blob/master/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L181
Type payloadType = payload.GetType();
if (!s_exceptionProperties.TryGetValue(payloadType, out PropertyInfo? propertyInfo))
{
propertyInfo = payload.GetType()
.GetProperties()
.FirstOrDefault(p => typeof(Exception).IsAssignableFrom(p.PropertyType));
s_exceptionProperties.TryAdd(payloadType, propertyInfo);
}
return propertyInfo?.GetValue(payload) as Exception;
}
}