Exception object loses stack trace when passed to Error(object message)

I noticed that when calling Log.Error(exception) with the NetCoreLogLogger (and likely other adapters), the exception is simply converted to a string via ToString() rather than being passed to the proper ILogger.LogError(Exception, string) overload:

public virtual void Error(object message)
{
    Log.LogError(message.ToString());
}

This means we lose structured exception data, proper stack trace formatting, and inner exception handling.

I see this was fixed for NLogLogger in PR #1210 (released in v5.8) by checking if the object is an Exception:

if (message is Exception ex)
    log.Error(ex, ex.GetType().Name);
else
    log.Error(message.ToString());

Could the same fix be applied to NetCoreLogLogger and other adapters? Something like:

public virtual void Error(object message)
{
    if (message is Exception ex)
        Log.LogError(ex, ex.Message);
    else
        Log.LogError(message?.ToString());
}

This would maintain backward compatibility while ensuring exceptions are logged correctly when passed directly to Error().

Thanks!

I think you mean NetCoreLog since there’s no NetCoreLogLogger class. The message is supposed to be the first parameter and the Exception (if exists) the 2nd param. I don’t really like supporting incorrect API usage but I’ve added this change in this commit which is now available from the latest v10.0.5+ which is now available in pre-release packages.

Note you should be able to get the behavior you want with an extension method, where as Exception is more specific than object it should be used when logging an error with a single Exception parameter:

public static class LogExtensions
{
    public static void Error(this ILog log, Exception message) => 
        log.Error(message.GetType().Name, message); 
}
1 Like