Question

I'm using the stomp.py library to get JSON messages from over a network. I've adapted the simple example they give here which uses a callback to provide message handling.

But I made a simple error when I modified that callback- for example, I called json.load() instead of json.loads() when trying to parse my JSON string.

class MyListener(object):
    def on_message(self, headers, message):
        data = json.load(message)           ## Should be .loads() for a string!

Usually that would be fine- it would AttributeError and I'd see a traceback. But in this case Python prints:

No handlers could be found for logger "stomp.py"

... no traceback, no crash out, and that was all. Very confusing to debug and find out what I did wrong! I was expecting at least the normal traceback along the lines of:

Traceback (most recent call last):
  File "./ncl/stomp.py-3.1.3/stompJSONParser.py", line 32, in <module>
    [etc etc ...]

... rather than it borking the whole listener. I guess it's because that happens on a different thread?

Now that I've worked out it's like a kind of runtime error in the callback I at least know I've done something wrong when it errors- but if it just spews that error for every mistake I make rather than giving me some kind of useful message, it makes it a bit difficult to code.

What causes this? And what could I do to get the regular, more verbose traceback back?

Was it helpful?

Solution

Looks like its expecting a log handler from the Python Logging Module to be set up in order to capture output. There are lots of possible configurations for logging. But for simple debugging I would use something along the lines of

import logging
logging.basicConfig(level=logging.DEBUG)

That should capture all output of log level DEBUG and above. Read the logging docs for more info :)

OTHER TIPS

Instructions for getting a logger (which is what is being asked for directly) can be found here, but the verbose traceback is suppressed.

If you take a look at the code which is calling on_message, you'll notice that that block is in a try block without an except.

Line 703 is where the method is actually called:

        notify_func = getattr(listener, 'on_%s' % frame_type)
        notify_func(headers, body)

which is in method __notify (declared on line 639):

def __notify(self, frame_type, headers=None, body=None):

These are the times when it is not in a try block:

  • 331 (for the connected event)
  • 426 for the send event
  • 743 for disconnected

But the time when message is called is line 727:

# line 719
try:
    # ....
    self.__notify(frame_type, headers, body)

In the end I grabbed the logger by name and set a StreamHandler on it:

import logging

log = logging.getLogger('stomp.py')
strh = logging.StreamHandler()
strh.setLevel(logging.ERROR)
log.addHandler(strh);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top