HangfireIO / Hangfire

An easy way to perform background job processing in .NET and .NET Core applications. No Windows Service or separate process required
https://www.hangfire.io
Other
9.19k stars 1.68k forks source link

MaxLinesInExceptionDetails is kind of broken #1947

Open LordJZ opened 2 years ago

LordJZ commented 2 years ago

Consider this piece of code in a job in default configuration:

try
{
    throw new Exception("test exception message");
}
catch (Exception e)
{
    e.Data["OriginalStackTrace"] = string.Join("\r\n", Enumerable.Repeat("abc", 1000)) + "\r\n" + e.StackTrace;
    throw;
}

The exception details get correctly truncated to 100 lines, but then the html formatter fails and prints nothing: image

In general, it would be nice to be able to attach multiple values to any job state, including Succeeded and Failed, to avoid having to jump through hoops like this.

odinserj commented 2 years ago

Thanks, but can you please tell me why one needs to modify the e.Data["OriginalStackTrace"] object?

LordJZ commented 2 years ago

Thanks, but can you please tell me why one needs to modify the e.Data["OriginalStackTrace"] object?

It is essential to attach multiple values to any job state. These can be extended error messages, exception information, logs, waiting and rescheduling information, server data, user identifiers, any context information etc.

Basically, the business requirement is this: Given a step in a job, any and all input and output and error info, and also every piece of information possibly related to the job step, must be immediately available at the same location where any other job info is provided. This means I must put all of that into Hangfire Dashboard, email reports, cloud log archives, Windows Event Viewer, mobile push notifications. The architecture for structured logging exists basically everywhere out of the box, but it is somewhat difficult with Hangfire, so I copy the text that is written to Windows Event Logs into e.Data["OriginalStackTrace"] which makes it nicely printed in Hangire Dashboard.

For example, in the exact same place where I learn that a job succeeded there must also be information on what "succeeded" means. For a file processing job, the minimum required info is: the number of files process, at least one example of a processed file path and name, some info on the processed contents, some info on the outputs. It is essential to display this information exactly in the same place that displays the fact that a job succeeded because it makes it possible for a human to confidently confirm that job has really succeeded by using visual pattern recognition, rather then mandatory check lists. In other words, it makes human mistakes much less likely.

Another way to think about is this: In the previous century errors were basically scalars, e.g. see windows error codes or pieces of text (e.g. the infamous throw "something";). But we are in the good times now; we throw Exceptions which provide rich error information with stack traces and other pieces of data necessary to diagnose the problem, so one single string return value is not enough.