jbogard / MediatR

Simple, unambitious mediator implementation in .NET
Apache License 2.0
11.06k stars 1.17k forks source link

Question: Why IRequestExceptionHandler is not catching? #1040

Closed renato04 closed 2 weeks ago

renato04 commented 3 months ago

Hello! I have declared my handlers as following

public interface IRequestWrapper<T> : IRequest<Response<T>> where T : notnull
{ }
public interface IHandlerWrapper<TIn, TOut> : IRequestHandler<TIn, Response<TOut>>
    where TIn : notnull, IRequestWrapper<TOut>
    where TOut : notnull    
{ }

public interface IRequestExceptionHandlerWrapper<TIn, TOut, TException> : IRequestExceptionHandler<TIn, Response<TOut>, TException>
    where TIn : notnull, IRequestWrapper<TOut>
    where TOut : notnull
    where TException : Exception
{}

public class GlobalRequestExceptionHandler<TIn, TOut, TException> : IRequestExceptionHandlerWrapper<TIn, TOut, TException>
    where TIn : notnull, IRequestWrapper<TOut>
    where TOut : notnull
    where TException : Exception
{
    private readonly ILogger<GlobalRequestExceptionHandler<TIn, TOut, TException>> _logger;
    public GlobalRequestExceptionHandler(
       ILogger<GlobalRequestExceptionHandler<TIn, TOut, TException>> logger)
    {
        _logger = logger;
    }

    public Task Handle(TIn request, TException exception, RequestExceptionHandlerState<Response<TOut>> state, CancellationToken cancellationToken)
    {
        var ex = exception.Demystify();
        _logger.LogError(ex, "Something went wrong while handling request of type {@requestType}", typeof(TIn));
        var response = Response.Fail<TOut>("A server error ocurred", statusCode: 500);
        state.SetHandled(response);
        return Task.CompletedTask;
    }
}

public record Request() : IRequestWrapper<RequestResponse>;
public record RequestResponse();

public class  RequestCommandHandler : IHandlerWrapper<Request, RequestResponse>
{
    public async Task<Response<RequestResponse>> Handle(Request request, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }
}   

Here is the DI configuration

builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
builder.Services.AddScoped(typeof(IRequestExceptionHandler<,,>), typeof(GlobalRequestExceptionHandler<,,>));

My issue the GlobalRequestExceptionHandler is not catching the exception. Could anyone help me?

serber commented 3 months ago

It's because IRequestExceptionHandlerWrapper is open generic and it's first parameter generic too

Try register GlobalRequestExceptionHandler like this

services.AddScoped(typeof(IRequestExceptionHandler<Request, Response<RequestResponse>, NotImplementedException>), typeof(GlobalRequestExceptionHandler<Request, RequestResponse, NotImplementedException>));

And have a look to MediatR.Registration.ServiceRegistrar class, which registering dependencies. You can also debug it =)

github-actions[bot] commented 1 month ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

github-actions[bot] commented 2 weeks ago

This issue was closed because it has been stalled for 14 days with no activity.