xpat error in xmlrp client. How to inspect data.

N

News123

Hi,

I'm havign a small xmlrpc client, which works normally fine.
(xmlrpc via https)

Sometimes however I receive an Exception about an expat error.


The output, that I receive is:
File "C:\mycode\myrpcclient.py", line 63, in upload_chunk
rslt = myrpcclient.call()
File "C:\Python26\lib\xmlrpclib.py", line 1199, in __call__
return self.__send(self.__name, args)
File "C:\Python26\lib\xmlrpclib.py", line 1489, in __request
verbose=self.__verbose
File "C:\Python26\lib\xmlrpclib.py", line 1253, in request
return self._parse_response(h.getfile(), sock)
File "C:\Python26\lib\xmlrpclib.py", line 1387, in _parse_response
p.feed(response)
File "C:\Python26\lib\xmlrpclib.py", line 601, in feed
self._parser.Parse(data, 0)
ExpatError: syntax error: line 1, column 0


In order to continue debugging I'd like to dump the received http data,
which "C:\Python26\lib\xmlrpclib.py", line 601 tried to parse without
succes.

How can I do this?

thanks for any suggestions


N
 
G

Gabriel Genellina

I'm havign a small xmlrpc client, which works normally fine.
(xmlrpc via https)

Sometimes however I receive an Exception about an expat error.


The output, that I receive is:
File "C:\mycode\myrpcclient.py", line 63, in upload_chunk
rslt = myrpcclient.call()
File "C:\Python26\lib\xmlrpclib.py", line 1199, in __call__
return self.__send(self.__name, args)
File "C:\Python26\lib\xmlrpclib.py", line 1489, in __request
verbose=self.__verbose
File "C:\Python26\lib\xmlrpclib.py", line 1253, in request
return self._parse_response(h.getfile(), sock)
File "C:\Python26\lib\xmlrpclib.py", line 1387, in _parse_response
p.feed(response)
File "C:\Python26\lib\xmlrpclib.py", line 601, in feed
self._parser.Parse(data, 0)
ExpatError: syntax error: line 1, column 0


In order to continue debugging I'd like to dump the received http data,
which "C:\Python26\lib\xmlrpclib.py", line 601 tried to parse without
succes.

How can I do this?

a) Use the standard cgitb module (despite its name, it is useful outside
CGI scripts)

b) Use the tb module available from http://pypi.python.org/pypi/tb

Both provide a more verbose traceback, including local variables at each
execution frame.

c) Replace ("monkey-patch") the feed() method with a more debug-friendly
version:

def feed(self, data):
try:
self._parser.Parse(data, 0)
except xmlrpclib.expat.ExpatError, e:
e.args += (data,)
raise

xmlrpclib.ExpatParser.feed = feed

(Or perhaps set e.data = data)

d) In your exception handler, walk the traceback object until you reach
the feed() call, and inspect the corresponding tb_frame.f_locals
dictionary.
 
N

News123

Hi Gabriel,

Gabriel said:
a) Use the standard cgitb module (despite its name, it is useful outside
CGI scripts)

b) Use the tb module available from http://pypi.python.org/pypi/tb
I'm currently using the default module traceback and code, which looks
roughly like:

try:
xmlrpccall()
except Exception as e:
ex_type,ex_value,e_b = sys.exc_info()
tbstring = traceback.format_exc()
logging.error('%s:%s:%s' % (ex_type,ex_value,tbstring)


do cgitb or tb really provide much more info?

Both provide a more verbose traceback, including local variables at each
execution frame.

c) Replace ("monkey-patch") the feed() method with a more debug-friendly
version:

def feed(self, data):
try:
self._parser.Parse(data, 0)
except xmlrpclib.expat.ExpatError, e:
e.args += (data,)
raise

xmlrpclib.ExpatParser.feed = feed

Well, the monkey patch seems to be THE solution for my problem. Thanks a
lot.
Now I'll just have to wait till the problem shows up again.
Probably I'll just display the backtrace in the except section.
(Or perhaps set e.data = data)

d) In your exception handler, walk the traceback object until you reach
the feed() call, and inspect the corresponding tb_frame.f_locals
dictionary.

How can I walk a traceback? For the current problem the the monkeypatch
should be good enough, but for other cases it might be good to know.



bye

N
 
G

Gabriel Genellina

I'm currently using the default module traceback and code, which looks
roughly like:

try:
xmlrpccall()
except Exception as e:
ex_type,ex_value,e_b = sys.exc_info()
tbstring = traceback.format_exc()
logging.error('%s:%s:%s' % (ex_type,ex_value,tbstring)


do cgitb or tb really provide much more info?

Well, for each frame along the stack, cgitb shows the value of all
function arguments, the value of each name referenced, and a few more
lines of code around the current one. It's rather verbose, but doesn't
include all local variables.

The tb module shows -also for each frame along the stack- the value of all
its local names (but doesn't include any global one).

Just try both of them and see which one you like most.
How can I walk a traceback? For the current problem the the monkeypatch
should be good enough, but for other cases it might be good to know.

Each traceback object is linked to the next one via its tb_next attribute.
But inspect.trace() builds a list of traceback records that may be easier
to handle; see the inspect module documentation. You can identify the
desired frame with its filename and function name, and then access its
local variables with f_locals.
I did something like that to gather context information for errors
happening in a third party library that were hard to diagnose otherwise.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top