1

I have asp.net core 2.1 application along with HangFire 1.6.17. HangFire is configured to execute a background job at certain interval. The background job calls external API using HttpClient. If the http call fails, then the method throws custom exception with metadata. Idea is hangfire will log the exception with metadata. I followed best-practices-for-exceptions to create exception

public class MyHttpRequestException : Exception
{
    public string Content { get; private set; }
    public string RequestUri { get; private set; }
    public string HttpResponse { get; private set; }

    public MyHttpRequestException()
    {
    }

    public MyHttpRequestException(string message)
        : base(message)
    {
    }


    public MyHttpRequestException(string message, Exception innerException)
        : base(message, innerException)
    {

    }

    public MyHttpRequestException(string message, string content, string httpResponse, string requestUri) 
        : base(message)
    {
        Content = content;
        RequestUri = requestUri;
        HttpResponse = httpResponse;
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(base.ToString());
        sb.AppendLine();
        sb.AppendLine();
        sb.AppendLine("Content");
        sb.AppendLine(Content);
        sb.AppendLine("RequestUri");
        sb.AppendLine(RequestUri);
        sb.AppendLine("HttpResponse");
        sb.AppendLine(this.HttpResponse);

        return sb.ToString();
    }
}

I also have extension method for HttpResponseMessage which ensures API request is successful, and if not throws MyHttpRequestException

public static class HttpResponseMessageExtensions
{
    public static async Task EnsureSuccessStatusCodeAsync(this HttpResponseMessage response)
    {
        if (response.IsSuccessStatusCode)
        {
            return;
        }

        var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        var httpResponse = response.ToString();
        var requestUri = response.RequestMessage.RequestUri.ToString()
        if (response.Content != null)
            response.Content.Dispose();


        throw new MyHttpRequestException("Error while making http request.", content, httpResponse, requestUri);
    }
}

Here is my background Job which is invoked by Hangfire recurring job scheduler

public async Task DoSomething(string url)
{
    var response  = await _httpClient.GetAsync(url)
    await response.EnsureSuccessStatusCodeAsync();  

    // do something here if everything is okay  
}

Issue
When EnsureSuccessStatusCodeAsync method throws MyHttpRequestException then Hangfire logs the exception as expected, and i see that in HangFire's dashboard. However Hangfire only logs Exception message and stack trace. I don't see my custom properties are being logged ( ie. Content, RequestUri, HttpResponse)

In clssic .NET we use SerializationInfo like this SO post
How do i create a custom exception in .NET Core so metadata will also get logged?

Note:
When the MyHttpRequestException gets thrown i noticed exception's ToString() method is getting called however, i dont see whatever ToString() returns is getting logged by Hangfire. I dont know if this is hangfire issue, or i need to implement MyHttpRequestException is different way.

2 Answers 2

0

The stack trace that you see in Dashboard is formatted. You can see here and here.

Because this custom stack trace format you can see your custom properties.

Sign up to request clarification or add additional context in comments.

1 Comment

so whats the solution?
0

I know its old question, but still:

You can use hanfire console to write your custom logs to the job console

public async Task DoSomething(string url, PerformContext context)
{
    var response  = await _httpClient.GetAsync(url)
    await response.EnsureSuccessStatusCodeAsync();  
    context.WriteLine($"Log Something");
    
    // do something here if everything is okay  
}

when registering the job, put null for PerformContext, hangfire will substitute its value when job is executed.

this also gives other console features like progress bar etc.

you will need to install Hangfire.Console.Extensions nuget.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.