NickCraver / StackExchange.Exceptional

Error handler used for the Stack Exchange network
https://nickcraver.com/StackExchange.Exceptional/
Apache License 2.0
862 stars 170 forks source link

How to get HttpContext in GetCustomData? #201

Closed DavidDeSloovere closed 3 years ago

DavidDeSloovere commented 3 years ago

Some docs mention HttpContext parameter for GetCustomData, but I think this parameter has been removed.

How can we fex. get the User and its claims into the custom data?

An ASP.NET Core build would benefit from an HttpContextAccessor that gets injected into the action.

NickCraver commented 3 years ago

If you indeed need HttpContext here, then HttpContextAccessor is exactly what you'd use. Note though you do not need it injected, it's an AsyncLocal<T> backed primitive which means you can have a static reference to that accessor and use it in the GetCustomData() method if you want! Be sure to use a try/catch here if you think that'll blow up though. I guard against an overall explosion from GetCustomData a level up, but if you had a chance at capturing anything past an explosion, you wouldn't get that data it/when it does go boom.

I'm fixing up the docs reference in #202 :)

DavidDeSloovere commented 3 years ago

Something like this would be acceptable? My IHttpContextAccessor isn't static, but Startup is only created once (I think).

// all other code has been removed
public class Startup
{
    private IHttpContextAccessor? _httpContextAccessor;

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddExceptional(
            settings =>
            {
                settings.GetCustomData = (exception, data) =>
                {
                    var user = _httpContextAccessor?.HttpContext?.User;
                    if (user != null)
                    {
                        data.Add("PersonId", user.GetPersonId().ToString(CultureInfo.InvariantCulture));
                    }
                };
            });
    }

    public void Configure(
        IApplicationBuilder app,
        IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
}