How to send Error Status back to client using RPC TempQueue method?

I am using the RPC pattern with RabbitMQ to make client calls to a service that responds back on the TempQueueName. I pass some header information in the RabbitMQ Message Meta collection that I then use to create a basic request with header fields (from Meta) to call the service on the ServiceStack server.

When the service on the server handles the request fine the response object is populated and returned through the queues to the client.

Problem is when I have an error happen and want to return the Error Code and Message back to the client. In my registered processMessageFN method I create and return an error response, but the client is returned the Message object without the Error object property set. And the ResponseDTO object in the body has all members set to null. I’ve tried a number of things, but haven’t found a way to return an error code and message in the Message object back to the client. I do not want to add error fields to each response dto as they are used with other hosts. Any help or direction would be greatly appreciated!

CLIENT CODE…

private void CallMQ()
{

   IMessage<R> responseMsg;

    mqClient.Publish((new Message<T>(request) { ReplyTo = replyMQ 
                                                                              }).PopulateMeta(this.Request));

    responseMsg = mqClient.Get<R>(replyMQ, TimeSpan.FromSeconds(WaitInSeconds));

    mqClient.Ack(responseMsg);

    //At this point responseMsg.Error is set to null and body's response dto has null members.

}

SERVER CODE…

public override object OnServiceException(IRequest httpReq, object request, Exception ex)
{
     //Log some errors...

     return null;
}

//Registered processMessageFN
private object ProcessServiceCall<T>(IMessage<T> msg)
{
   //Creates a request and populates header from meta collection
    var request = new BasicRequest { Verb = HttpMethods.Post }.PopulateRequest(msg as Message);

    var response = this.ServiceController.ExecuteMessage(msg, request);    

    if (response.IsErrorResponse())
      {
            HttpError error = (HttpError)response;
             //*NOTE - I validate error field is populated.
            return ServiceStack.HttpResultUtils.CreateErrorResponse(error);  
       }

       return response;
}

If this is using ServiceStack’s ExecuteMessage, Error Responses are retried and published to the DLQ, so your code should look something like:

var responseMsg = mqClient.Get<R>(replyMQ, TimeSpan.FromSeconds(WaitInSeconds));

if (responseMsg == null)
{
    var dlqMsg = mqClient.Get<T>(QueueNames<T>.Dlq);
    mqClient.Ack(dlqMsg);
    Console.WriteLine(dlqMsg.Error.ErrorCode + ":" + dlqMsg.Error.Message);
}

I’ve never seen a message get written to the DLQ. I’m using the ReplyTo which uses a temporary queue for the response. The error is handled on the server I just want to return a standard error code using the IMessage for every service call made through the Message Queues. I can set the IMessage objects metaHeader field going into the service, but I can’t seem to change the IMessage object when responding back to the temp queue. I can only seem to modify and return what’s in the IMessage GetBody. Any ideas how I can set the IMessage wrapper object values when I return the object from the ProcessServiceCall(IMessage msg) method? Or is this a limitation of the implementation with RabbitMQ? Thanks much.

All MQ Servers have the same behavior where Exceptions thrown in Services are automatically sent to the Request DTOs DLQ, including ReplyTo messages.

The way Errors are populated on Messages is to populate the IMessage.Error property which for RabbitMQ we send in the IBasicProperties.Headers[“Error”] property.

I’m registering my Handler differently so I don’t believe that is the case. I have both the overriden OnServiceException called and my processExceptionEx called. So I think it then returns back to the client and doesn’t place the message in the dlq. Which that process flow is fine for my use case I’m just trying to figure out the best way to get an error code back in the return object out of the processMessageFn method that I registered.

mqServer.RegisterHandler(processMessageFn, processExceptionEx, serviceInstances);

I think I solved my problem after doing some research. I had to return the IMessage RequestDTO instead of returning the IMessage ResponseDTO; otherwise, the Error property was not retained.