Fault handling for request/response messages

1,864 views
Skip to first unread message

Jacenty

unread,
Mar 5, 2012, 4:53:06 AM3/5/12
to masstransit-discuss, jacek...@kruksa.pl
Hello,

I,m using MassTransit (v. 2.0.1.2) with RabbitMQ. I'm not sure, how to
work with faults.
When consuming simple publish/subscribe messages, if an exception in
message handler occurs, then the fault message is generated
automatically, and can be received by the client as Fault<Original
message type>.
But in the case of request response message, if an exception occurs, I
have to catch it and then call the GenerateFault() method.
The strangest thing is, that it seems, that in the second case the
fault message is generated, but it's not received by the client app.

Regards,
Jacek Hełka

Dru Sellers

unread,
Mar 5, 2012, 4:47:32 PM3/5/12
to masstrans...@googlegroups.com
@chris?


--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/masstransit-discuss?hl=en.


Chris Patterson

unread,
Mar 6, 2012, 10:52:41 AM3/6/12
to masstrans...@googlegroups.com
This is something I would need to see in an example script or unit test, as I'm having trouble following you.

An exception on the request side of a request/response seems like an application concern, not an MT/Fault concern.

Stanislav Perekrestov

unread,
Sep 14, 2012, 11:31:00 AM9/14/12
to masstrans...@googlegroups.com, jacek...@kruksa.pl
Hello.

This is an old post.
Anyway, does anybody have any thoughts on this?
Thanks.

Chris Patterson

unread,
Sep 14, 2012, 2:56:58 PM9/14/12
to masstrans...@googlegroups.com
I just published 2.6.3, which has the ability to handle faults in the
request/response using a x.HandleFault() handler.
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to
> masstransit-dis...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Stanislav Perekrestov

unread,
Sep 16, 2012, 12:47:00 PM9/16/12
to masstrans...@googlegroups.com
Hi.
It's awesome to have such functionality. Thanks!
Unfortunately it doesn't work for me :(

When a consumer sends a response using the
context.Respond(..) method then everything works fine, but when the consumer explicitly sends a fault a requester doesn't receive it.

My consumer looks like:

public void Consume(IConsumeContext<GetRequestedInformation> context)
        {
            try
            {
             ///...
             context.Respond(new  RequestedInformationResponse ()});
            }
            catch (SomeException e)
            {
                _log.ErrorFormat("An error has occured: {0}", e.Message);
                context.GenerateFault(new SomeException(e.Message));
         _log.Debug("A fault has been sent");
            }
}

I traced the consumer and I got the following:
2012-09-16 19:23:57.3799|DEBUG|MassTransit.Messages|RECV:rabbitmq://localhost/testbus_consumer:08cf623e-caa6-3bee-6c62-6d3f95580000: MyApp.GetRequestedInformation, MyApp
2012-09-16 19:23:57.3799|DEBUG|MyApp.GetRequestedInformationConsumer|Received a message
....
2012-09-16 19:23:59.3218|ERROR| MyApp.GetRequestedInformationConsumer|An error has occured: bla-bla
2012-09-16 19:23:59.3218|DEBUG|MyApp.GetRequestedInformationConsumer|A fault has been sent
2012-09-16 19:23:59.3389|DEBUG|MassTransit.Transports.Endpoint|Received Successfully: 08cf623e-caa6-3bee-6c62-6d3f95580000

I use the following approach to send a request and receive a response:

 static class ServiceBusExtensions
{
public static Task<TResponse> PublishRequestAsync<TRequest, TResponse>(this IServiceBus bus, TRequest request,
                                                                      TimeSpan timeout)
where TRequest : class
where TResponse : class
{
var source = new TaskCompletionSource<TResponse>();

bus.BeginPublishRequest(request, ar =>
                                {
                                try
                                {
                                bus.EndPublishRequest<TRequest>(ar);
                                }
                                catch (Exception ex)
                                {
                                source.SetException(ex);
                                }
                                }, null, x =>
                                         {
                                         x.Handle<TResponse>(source.SetResult);
/*I'm not sure that I use this API correctly*/   x.HandleFault(fault => source.SetException(new ServiceException(/*...*/)));
                                         x.HandleTimeout(timeout, source.SetCanceled);
                                         });

return source.Task;
}
}

Big thanks in advance!

Chris Patterson

unread,
Sep 16, 2012, 7:06:49 PM9/16/12
to masstrans...@googlegroups.com
You're not - throw an exception from the consumer, that will
automatically generate the fault for you. If you're sending the fault
yourself, use your own message type. Fault<T> is for when you don't
handle the exception yourself. If you are going to handle the
exception yourself, that's just another message type for your
application.

So if you want the automatic retry logic and everything, just throw
from your consumer and MT will handle the fault generation.

On Sun, Sep 16, 2012 at 11:47 AM, Stanislav Perekrestov
>> > masstransit-dis...@googlegroups.com.
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to
> masstransit-dis...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.

Stanislav Perekrestov

unread,
Sep 17, 2012, 12:14:32 PM9/17/12
to masstrans...@googlegroups.com
I've tried 2 mentioned approaches without any success :(

  1. If a consumer doesn't catch an exception and a requester looks like
public static Task<TResponse> PublishRequestAsync<TRequest, TResponse>(this IServiceBus bus, TRequest request,
                                                                      TimeSpan timeout)
where TRequest : class
where TResponse : class
{
var source = new TaskCompletionSource<TResponse>();

bus.BeginPublishRequest(request, ar =>
                                {
                                try
                                {
                                bus.EndPublishRequest<TRequest>(ar);
                                }
                                catch (Exception ex)
                                {
                                source.SetException(ex);
                                }
                                }, null, x =>
                                         {
                                         x.Handle<TResponse>(source.SetResult);
 x.HandleFault(fault =>
               {
Debugger.Break();
               source.SetException(new ServiceException());
               });
 x.HandleTimeout(timeout, source.SetCanceled);
                                         });

return source.Task;
}
2. If a consumer catches an exception, explicitly generates a fault 

context.GenerateFault(new SomeException(e.Message));

and a requester looks like  


internal static class ServiceBusExtensions
{
public static Task<TResponse> PublishRequestAsync<TRequest, TResponse>(this IServiceBus bus, TRequest request,
                                                                      TimeSpan timeout)
where TRequest : class
where TResponse : class
{
var source = new TaskCompletionSource<TResponse>();

bus.BeginPublishRequest(request, ar =>
                                {
                                try
                                {
                                bus.EndPublishRequest<TRequest>(ar);
                                }
                                catch (Exception ex)
                                {
                                source.SetException(ex);
                                }
                                }, null, x =>
                                         {
                                         x.Handle<TResponse>(source.SetResult);
  x.Handle<SomeException>(ex => { 
  Debugger.Break();
  source.SetException(new ServiceException(ex.Message, ex));
   });
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to

Chris Patterson

unread,
Sep 17, 2012, 1:32:22 PM9/17/12
to masstrans...@googlegroups.com
This is the unit test for the fault handler.

https://github.com/MassTransit/MassTransit/blob/master/src/MassTransit.Tests/PublishRequest_Specs.cs#L253

Also, is there a reason you aren't using the native TPL support with
your project instead of hand-coding it?

On Mon, Sep 17, 2012 at 11:14 AM, Stanislav Perekrestov
>> >> > masstransit-dis...@googlegroups.com.
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > masstransit-dis...@googlegroups.com.
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to
> masstransit-dis...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/masstransit-discuss/-/E4HjchiFSCAJ.

Stanislav Perekrestov

unread,
Sep 17, 2012, 4:23:45 PM9/17/12
to masstrans...@googlegroups.com
I guess I'm doing something wrong.
At least I can't find extensions methods that add TPL support.

MassTransit.RequestResponseExtensions contains methods that support the  APM patterns.
I "implemented the wheel" because I'd like to use async/await withing request/response pattern. I wasn't able to find it out-of-box.
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to

Stanislav Perekrestov

unread,
Sep 18, 2012, 2:14:06 PM9/18/12
to masstrans...@googlegroups.com
Hello.

If I understand you correctly you suggest to send a predefined error message :

context.Respond(new SomethingWrongHappened());

Also I'd like to note that IConsumeContext makes developers to explicitly call the context.GenerateFault method :)
For instance I'd spent several hrs to get it work until I thought of a special message :))))) https://gist.github.com/3744667 
Maybe it'll be useful to mention the semantics of this method in docs...

Thanks a lot!

On Monday, September 17, 2012 2:06:50 AM UTC+3, Chris Patterson wrote:
>> > masstransit-discuss+unsub...@googlegroups.com.
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to
> masstransit-discuss+unsub...@googlegroups.com.

Chris Patterson

unread,
Sep 18, 2012, 5:54:05 PM9/18/12
to masstrans...@googlegroups.com
Or just throw an exception if it's truly an exception.

On Tue, Sep 18, 2012 at 1:14 PM, Stanislav Perekrestov
>> >> > masstransit-dis...@googlegroups.com.
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > masstransit-dis...@googlegroups.com.
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to
> masstransit-dis...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/masstransit-discuss/-/rjBeXKvmF7IJ.

Stanislav Perekrestov

unread,
Sep 19, 2012, 9:43:27 AM9/19/12
to masstrans...@googlegroups.com
Regarding my own wheel:

The goal is to handle a fault or a response message that indicate an error and pass it as a Task error:

The current API is:

var task = _bus.PublishRequestAsync(message, cfg =>
{
cfg.Handle<TResponse>(x => { /*.Why I need this callback?..*/});
cfg.Handle<ServiceInternalError>(x => { /*How to pass an exception to the current task? */ });
cfg.HandleFault(fault => { /*How to pass a fault as an exception to the current task? */  });
cfg.SetTimeout(TimeSpan.FromSeconds(10));
}).GetResponseTask<TResponse>();

Thanks.
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to

Chris Patterson

unread,
Sep 19, 2012, 9:45:21 AM9/19/12
to masstrans...@googlegroups.com
Well, a fault is not an exception, so if you want to pass an exception
out the task, you should throw one in the fault handler.

I debated just making the default behavior of failing the task if an
unhandled fault was received, but didn't add that as it felt wrong to
force it on you.

On Wed, Sep 19, 2012 at 8:43 AM, Stanislav Perekrestov
>> >> >> > masstransit-dis...@googlegroups.com.
>> >> >> > To view this discussion on the web visit
>> >> >> >
>> >> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >> >
>> >> >> >
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups
>> >> > "masstransit-discuss" group.
>> >> > To post to this group, send email to masstrans...@googlegroups.com.
>> >> > To unsubscribe from this group, send email to
>> >> > masstransit-dis...@googlegroups.com.
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >> >
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > masstransit-dis...@googlegroups.com.
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/E4HjchiFSCAJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to
> masstransit-dis...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/masstransit-discuss/-/4Uv54XFMe7sJ.

Stanislav Perekrestov

unread,
Sep 19, 2012, 9:57:32 AM9/19/12
to masstrans...@googlegroups.com
Thanks for the reply.

BTW, nevertheless If I use a special message for an error I can't throw an exception in a handler and get it in Task.Exception property
var task = _bus.PublishRequestAsync(message, cfg =>
{
cfg.Handle<TResponse>(x => { });
cfg.Handle<ServiceInternalError>(x => { throw new SomeException("x.ErrorMessage);});
......
}

....

task.Exception --- I just what to get SomeException here :)

The code from gist allows this.
I suppose it's useful when we need to simulate RPC using MT.
>> >> >> > To view this discussion on the web visit
>> >> >> >
>> >> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >> >
>> >> >> >
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups
>> >> > "masstransit-discuss" group.
>> >> > To post to this group, send email to masstrans...@googlegroups.com.
>> >> > To unsubscribe from this group, send email to
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >> >
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/E4HjchiFSCAJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to

Gustav Ösgård

unread,
Oct 3, 2013, 9:33:23 AM10/3/13
to masstrans...@googlegroups.com
Hi,

So when are you suppose to use context.GenerateFault() ?

Regards,
Gustav
>> >> >> > To view this discussion on the web visit
>> >> >> >
>> >> >> > https://groups.google.com/d/msg/masstransit-discuss/-/TdMts_NWD0QJ.
>> >> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >> >
>> >> >> >
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups
>> >> > "masstransit-discuss" group.
>> >> > To post to this group, send email to masstrans...@googlegroups.com.
>> >> > To unsubscribe from this group, send email to
>> >> > To view this discussion on the web visit
>> >> > https://groups.google.com/d/msg/masstransit-discuss/-/R2TTzc7bAHsJ.
>> >> >
>> >> > For more options, visit https://groups.google.com/groups/opt_out.
>> >> >
>> >> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "masstransit-discuss" group.
>> > To post to this group, send email to masstrans...@googlegroups.com.
>> > To unsubscribe from this group, send email to
>> > To view this discussion on the web visit
>> > https://groups.google.com/d/msg/masstransit-discuss/-/E4HjchiFSCAJ.
>> >
>> > For more options, visit https://groups.google.com/groups/opt_out.
>> >
>> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to

Chris Patterson

unread,
Oct 3, 2013, 12:25:10 PM10/3/13
to masstrans...@googlegroups.com
You shouldn't usually, that's used by MT to publish a Fault in response to a consumer throwing an exception.


To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages