3

I have a XMS MQ Client app that is pulling off messages from a series of MQ endpoints. There are certain reason codes for which the process can continue, and for some that it should abort. For example a MQRC_Q_MGR_NOT_AVAILABLE 2059 for one endpoint shouldn't abort the whole process. Consequently I would like to check for this reason code.

cf = factoryFactory.CreateConnectionFactory();
foreach (Endpoint e in env.GetEndpoints())
{
    Console.WriteLine("Consuming messages from endpoint {0}({1})", e.host, e.port);

    // Set the properties
    SetConnectionProperties(cf, e);

    try
    {
        ReceiveMessagesFromEndpoint(cf);
    }
    catch (XMSException ex)
    {
        Console.WriteLine("XMSException caught: {0}", ex);
        Console.WriteLine("Error Code: {0}", ex.ErrorCode);
        Console.WriteLine("Error Message: {0}", ex.Message);
    }
}

Problem is that the only attributes available on the XMSException to examine are ex.ErrorCode and ex.Message, which are respectively:

Error Code: CWSMQ0006

and

Error Message: CWSMQ0006E: An exception was received during the call to the method ConnectionFactory.CreateConnection: CompCode: 2, Reason: 2059.

I can see the Reason in the Message, but can't find a method or attribute to retrieve it.

Cœur
  • 37,241
  • 25
  • 195
  • 267
chughts
  • 4,210
  • 2
  • 14
  • 27

2 Answers2

2

There are probably 2 ways to do it

1) You can use the LinkedException

Something like the following

    try
    {
    }
    catch (XMSException e)
    {
      if(e.LinkedException!=null)
        Console.WriteLine(e.LinkedException.Message);
      else
        Console.WriteLine(e);
    }

2) Reference amqmdnet.dll as well to the project and use MQException.Something like

    try
    {
    }
    catch (XMSException e)
    {
      if(e.LinkedException!=null)
      {
        IBM.WMQ.MQException inner = (IBM.WMQ.MQException)e.LinkedException;
            Console.WriteLine("Reason:"+ inner.ReasonCode);
      }
      else
        Console.WriteLine(e);
    }
subbaraoc
  • 1,123
  • 1
  • 8
  • 27
  • `ex.LinkedException.Message` is the reason code, but rather than testing against a hardcoded string of `2059` eg. `if (! "2059".Equals(ex.LinkedException.Message))` is there a defined constant I can compare against? – chughts Nov 20 '19 at 16:19
  • If i understand your question correctly are you saying instead of 2059 you want to use something like "IBM.XMS.MQC.MQRC_Q_MGR_NOT_AVAILABLE" – subbaraoc Nov 20 '19 at 16:25
  • Yes, that is it, though now its comparing an int with a ToString with a string. – chughts Nov 20 '19 at 16:43
0

Solution by OP

Based on accepted answer, a 'working' code is:

cf = factoryFactory.CreateConnectionFactory();
foreach (Endpoint e in env.GetEndpoints())
{
    Console.WriteLine("Consuming messages from endpoint {0}({1})", e.host, e.port);

    // Set the properties
    SetConnectionProperties(cf, e);

    try
    {
        ReceiveMessagesFromEndpoint(cf);
    }
    catch (XMSException ex)
    {
        Console.WriteLine("XMSException caught: {0}", ex);
        Console.WriteLine("Error Code: {0}", ex.ErrorCode);
        Console.WriteLine("Error Message: {0}", ex.Message);

        if (ex.LinkedException != null && 
                IBM.XMS.MQC.MQRC_Q_MGR_NOT_AVAILABLE.ToString().Equals(ex.LinkedException.Message))

        {
            Console.WriteLine("Queue Manager on this endpoint is not available");
            Console.WriteLine("Moving onto next endpoint");
            continue;
        }
        Console.WriteLine("Unexpected Error - Aborting");
        throw;
    }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267