title: Handling errors/exceptions in a mediator pipeline using CQRS?
body: <p>I'm trying to follow <a href="https://lostechies.com/jimmybogard/2014/09/09/tackling-cross-cutting-concerns-with-a-mediator-pipeline/" rel="noreferrer">this post</a> by Jimmy Bogard to implement a mediator pipeline so I can use pre/post request handlers to do some work. From the comments on that article I come to this <a href="https://gist.github.com/NotMyself/579f94e1aad6a022ddb9" rel="noreferrer">github gist</a>. I don't quite understand how to hook all of this up yet, so here is my first go. FYI - I'm using Autofac for DI and Web Api 2. Following CQRS, here is a query.</p>
  
  <pre><code>public class GetAccountRequest : IAsyncRequest&lt;GetAccountResponse&gt;
  {
      public int Id { get; set; }
  }
  
  //try using fluent validation
  public class GetAccountRequestValidationHandler 
      : AbstractValidator&lt;GetAccountRequest&gt;, IAsyncPreRequestHandler&lt;GetAccountRequest&gt;
  {
      public GetAccountRequestValidationHandler() {
          RuleFor(m =&gt; m.Id).GreaterThan(0).WithMessage("Please specify an id.");
      }
  
      public Task Handle(GetAccountRequest request) {
          Debug.WriteLine("GetAccountPreProcessor Handler");   
          return Task.FromResult(true);
      }
  }
  
  public class GetAccountResponse
  {
      public int AccountId { get; set; }
      public string Name { get; set; }
      public string AccountNumber { get; set; }
      public string Nickname { get; set; }
      public string PhoneNumber { get; set; }
      public List&lt;OrderAckNotification&gt; OrderAckNotifications { get; set; }
  
      public class OrderAckNotification {
          public int Id { get; set; }
          public bool IsDefault { get; set; }
          public string Description { get; set; }
          public string Type { get; set; }
      }
  }
  </code></pre>
  
  <p>GetAccountRequestHandler:</p>
  
  <pre><code>public class GetAccountRequestHandler 
      : IAsyncRequestHandler&lt;GetAccountRequest, GetAccountResponse&gt;
  {
      private readonly IRedStripeDbContext _dbContext;
  
      public GetAccountRequestHandler(IRedStripeDbContext redStripeDbContext)
      {
          _dbContext = redStripeDbContext;
      }
  
      public async Task&lt;GetAccountResponse&gt; Handle(GetAccountRequest message)
      {
          //some mapping code here.. omitted for brevity
          Mapper.AssertConfigurationIsValid();
  
          return await _dbContext.Accounts.Where(a =&gt; a.AccountId == message.Id)
              .ProjectToSingleOrDefaultAsync&lt;GetAccountResponse&gt;();
      }
  </code></pre>
  
  <p>Here is the current web api 2 controller showing the HttpGet.</p>
  
  <pre><code>[RoutePrefix("api/Accounts")]
  public class AccountsController : ApiController
  {
      private readonly IMediator _mediator;
  
      public AccountsController(IMediator mediator)
      {
          _mediator = mediator;
      }
  
      // GET: api/Accounts/2
      [Route("{id:int}")]
      [HttpGet]
      public async Task&lt;IHttpActionResult&gt; GetById([FromUri] GetAccountRequest request)
      {
          var model = await _mediator.SendAsync&lt;GetAccountResponse&gt;(request);
  
          return Ok(model);
      }
  }
  </code></pre>
  
  <p>Finally here is the dependency resolution code:</p>
  
  <pre><code>public void Configuration(IAppBuilder app)
  {
      var config = new HttpConfiguration();
  
      ConfigureDependencyInjection(app, config);
  
      WebApiConfig.Register(config);
      app.UseWebApi(config);
  }
  
  private static void ConfigureDependencyInjection(IAppBuilder app, 
      HttpConfiguration config)
  {
      var builder = new ContainerBuilder();
      builder.RegisterSource(new ContravariantRegistrationSource());
      builder.RegisterAssemblyTypes(typeof(IMediator).Assembly).AsImplementedInterfaces();
  
      builder.Register&lt;SingleInstanceFactory&gt;(ctx =&gt;
      {
          var c = ctx.Resolve&lt;IComponentContext&gt;();
          return t =&gt; c.Resolve(t);
      });
  
      builder.Register&lt;MultiInstanceFactory&gt;(ctx =&gt;
      {
          var c = ctx.Resolve&lt;IComponentContext&gt;();
          return t =&gt; (IEnumerable&lt;object&gt;)c.Resolve(
              typeof(IEnumerable&lt;&gt;).MakeGenericType(t));
      });
  
      //register all pre handlers
      builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
          .As(type =&gt; type.GetInterfaces()
              .Where(t =&gt; t.IsClosedTypeOf(typeof(IAsyncPreRequestHandler&lt;&gt;))));
  
      //register all post handlers
      builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
          .As(type =&gt; type.GetInterfaces()
              .Where(t =&gt; t.IsClosedTypeOf(typeof(IAsyncPostRequestHandler&lt;,&gt;))));
  
  
      //register all handlers
      builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
          .As(type =&gt; type.GetInterfaces()
              .Where(t =&gt; t.IsClosedTypeOf(typeof(IAsyncRequestHandler&lt;,&gt;)))
              .Select(t =&gt; new KeyedService("asyncRequestHandler", t)));
  
      //register pipeline decorator
      builder.RegisterGenericDecorator(typeof(AsyncMediatorPipeline&lt;,&gt;), 
          typeof(IAsyncRequestHandler&lt;,&gt;), "asyncRequestHandler");
  
      // Register Web API controller in executing assembly.
      builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
  
      //register RedStripeDbContext
      builder.RegisterType&lt;RedStripeDbContext&gt;().As&lt;IRedStripeDbContext&gt;()
          .InstancePerRequest();
  
      builder.RegisterType&lt;AutofacServiceLocator&gt;().AsImplementedInterfaces();
      var container = builder.Build();
  
      config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
  
      // This should be the first middleware added to the IAppBuilder.
      app.UseAutofacMiddleware(container);
  
      // Make sure the Autofac lifetime scope is passed to Web API.
      app.UseAutofacWebApi(config);
  }
  </code></pre>
  
  <p>I am getting into the GetAccountRequestValidationHandler. However, when the validation fails (an id of 0 was passed), how do I throw an exception or stop the execution of the pipeline? How do I return the .WithMessage?</p>