On 11/04/2019 09:39, Toralf Lund wrote:
On 10/04/2019 18:18, Gordon Sim wrote:
On 10/04/2019 10:10 am, Toralf Lund wrote:
Hi,

In one of my C++ "messaging" programs I sometimes use qpid::Messaging::Session::checkError() as a way to "rethrow" (in as somewhat loose sense) sender or receiver exceptions that were already caught elsewhere. I notice that the exceptions I then get are not quite the same as the original ones. I believe that with some past QPid versions, the exception type would actually be different. With more recent ones, it's the same, but it looks like the type is the same, but the error message is not there - what() returns an empty string.

Is that the expected behaviour? Are there any other cases where there is no error description?

What type of error is this for? TransportFailure? I would expect the what() message to be preserved.

It's a TransportFailure

 catch(const qpid::types::Exception &error) {
      std::cerr << "Exception \"" << error.what() << "\", address " << &error
        << ", type " << typeid(error).name() << "\n";

says

    Exception "", address 0x2237e80, type N4qpid9messaging16TransportFailureE

Original message is "Failed to connect (reconnect disabled)". I provoke that error into occurring by suspending execution (kill -STOP or Ctrl+Z), waiting for a while, then resuming.

I've now thrown together some of my code into a little test program - see attachment. It wants an exchange and subject string as arguments, and optionally "-b <broker>". Like I said, I'm using suspend + resume to get connection issues. The below shows a typical test run, with output. Note that I wait for a few seconds between "^Z" and "fg". Also, I don't consistently get this result, there are cases where I don't get any of the error messages, but a reconnect is still reported, or I see the 2nd message but not the first.

[toralf@osl-97214 ipc]$ ./qpidSendTst amq.topic sometopic
Open connection...
Connected to tcp:localhost:5672
Publish to amq.topic/sometopic OK
Publish to amq.topic/sometopic OK
Publish to amq.topic/sometopic OK
Publish to amq.topic/sometopic OK
Publish to amq.topic/sometopic OK
^Z
Suspended
[toralf@osl-97214 ipc]$ fg
./qpidSendTst amq.topic sometopic
Publish to amq.topic/sometopic OK
"Failed to connect (reconnect disabled)" when sending message to amq.topic/sometopic
Exception "", address 0x1703d40, type N4qpid9messaging16TransportFailureE
Open connection...
Connected to tcp:localhost:5672
Publish to amq.topic/sometopic OK
Publish to amq.topic/sometopic OK
^C

- T




- Toralf


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]



#include <qpid/messaging/Connection.h>
#include <qpid/messaging/Session.h>
#include <qpid/messaging/Message.h>
#include <qpid/messaging/Sender.h>
#include <qpid/messaging/Receiver.h>
#include <qpid/types/Exception.h>

#include <string>
#include <iostream>
#include <typeinfo>

#include <getopt.h>
#include <unistd.h>

class TestSender {
private:
  qpid::messaging::Connection connection_;
  qpid::messaging::Session session_;
  std::string exchange_, subject_;
  
  void updateConnection();
  bool publish(const std::string &messageText);
  bool publish(const qpid::messaging::Message &message);
public:
  void run();
  
  TestSender(const std::string &brokerUrls, const std::string &exchange, 
	    const std::string &subject);
};



void TestSender::updateConnection()
{
  if(!connection_.isOpen()) {
    std::cerr << "Open connection...\n";
    connection_.open();
    std::cerr << "Connected to " << connection_.getUrl() << "\n";
  }
  if(session_.isValid() && session_.hasError()) {
    session_.close();
    session_=qpid::messaging::Session();
  }
  if(!session_.isValid()) {
    session_=connection_.createSession();
  }
}

bool TestSender::publish(const qpid::messaging::Message &message)
{
  try {
    qpid::messaging::Sender sender;

    try {
      sender=session_.getSender(exchange_);
    } catch(qpid::messaging::KeyError &error) {
      std::string exchangeArgs=""; /// \todo For now
      std::string address=exchange_ + "; { " + exchangeArgs + " }";
      
      sender=session_.createSender(address);
    }
    
    sender.send(message);
  } catch(const qpid::types::Exception &error) {
    std::cerr << "\"" << error.what() << "\" when sending message to "
	      << exchange_ << "/" << message.getSubject() << "\n";
    
    return false;
  }
  std::cerr << "Publish to " << exchange_  << "/" << message.getSubject()
	    << " OK\n";
  
  return true;
}


bool TestSender::publish(const std::string &messageText)
{
  qpid::messaging::Message message;
  
  message.setSubject(subject_);
  message.setContent(messageText);
  
  return publish(message);
}



void TestSender::run()
{
  while(true) {
    try {
      updateConnection();
      sleep(1);
      publish("");
      session_.checkError();
    } catch(const qpid::types::Exception &error) {
      std::cerr << "Exception \"" << error.what() << "\", address " << &error
		<< ", type " << typeid(error).name() << "\n";
      sleep(1);
    } 
  }
}

TestSender::TestSender(const std::string &brokerUrls,
		       const std::string &exchange,
		       const std::string &subject) 
  : connection_((brokerUrls.empty()?"localhost":brokerUrls)),
    exchange_(exchange), subject_(subject)
{
  connection_.setOption("tcp_nodelay", true);
  connection_.setOption("heartbeat", 1);
}


int main(int argc, char* argv[])
{
  std::string messageBrokerUrls;
  int c;
  
  while((c=getopt(argc, argv, "b:"))>=0) {
    switch(c) {
    case 'b':
      if(!messageBrokerUrls.empty())
	messageBrokerUrls+=',';
      messageBrokerUrls+=optarg;
      break;
    }
  }
  if(argc>optind+1) {
    TestSender testSender(messageBrokerUrls, argv[optind], argv[optind+1]);
    
    testSender.run();
  } else {
    std::cerr << "Usage " << argv[0] << " [-b broker ...] exchange subject\n";
  }
  return 0;
}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to