class `InteractionBase` method `log` fails if received tuple, why it receives a tuple?
senaps opened this issue · 2 comments
Hello, our production code failed suddenly with strange error expected string, list found
[Failure instance: Traceback: <type 'exceptions.TypeError'>: sequence item 0: expected string, list found
/usr/lib64/python2.7/threading.py:812:__bootstrap_inner
/usr/lib64/python2.7/threading.py:765:run
/usr/lib64/python2.7/site-packages/twisted/_threads/_threadworker.py:46:work
/usr/lib64/python2.7/site-packages/twisted/_threads/_team.py:190:doWork
--- <exception caught here> ---
/usr/lib64/python2.7/site-packages/twisted/python/threadpool.py:250:inContext
/usr/lib64/python2.7/site-packages/twisted/python/threadpool.py:266:<lambda>
/usr/lib64/python2.7/site-packages/twisted/python/context.py:122:callWithContext
/usr/lib64/python2.7/site-packages/twisted/python/context.py:85:callWithContext
/usr/lib64/python2.7/site-packages/twisted/enterprise/adbapi.py:475:_runInteraction
/usr/lib64/python2.7/site-packages/twisted/enterprise/adbapi.py:465:_runInteraction
/usr/lib/python2.7/site-packages/twistar/dbconfig/base.py:144:_doselect
/usr/lib/python2.7/site-packages/twistar/dbconfig/base.py:79:executeTxn
/usr/lib/python2.7/site-packages/twistar/dbconfig/base.py:47:log
so, I traced my data all the way in the code and didn't find out where it's turned to a tuple, and then the logger fails.
def log(self, query, args, kwargs):
"""
Log the query and any args or kwargs using C{twisted.python.log.msg} if
C{InteractionBase.LOG} is True.
"""
if not InteractionBase.LOG:
return
log.msg("TWISTAR query: %s" % query)
if len(args) > 0:
try:
log.msg("TWISTAR args: %s" % ",".join(args))
except Exception as e:
pass
elif len(kwargs) > 0:
log.msg("TWISTAR kargs: %s" % str(kwargs))
I have added this try/catch
so that the code passes, but! how can I find out why is query
being turned to a tuple?
this is the query that is sent to the log function:
print str(query), type(query)
(['192.168.56.31'],): <type 'tuple'>
here is how Im using the data:
d = Attackers.find(where=['ip = ?', ip],limit=1)
d.addCallback(self._check_attacker, ip)
d.addErrback(self.handle_err)
where ip
is a string of "192.168.56.31". the funny thing is the code has been running up until now, and I can't get what has changed.
I have traced the data as follows:
dbobject.py - > select function
loger("in find where is: " + str(where))
in find where is: ['ip = ?', '192.168.56.31']
dabse.py -> select function:
select function where is: ['ip = ?', '192.168.56.31']
│select function whereToString is: ['ip = ?', '192.168.56.31']and: ['192.168.56
│.31']type: <type 'list'>
and then the log is:
log func query is: [SELECT * FROM attackers WHERE ip = %s LIMIT 1] args: (['192.168.56.31'],)
for :
loger("log func query is: [" + str(query) + "] args: ["+ str(args)+"] ")
Currently, my code runs with the following code:
def log(self, query, args, kwargs):
"""
Log the query and any args or kwargs using C{twisted.python.log.msg} if
C{InteractionBase.LOG} is True.
"""
if not InteractionBase.LOG:
return
log.msg("TWISTAR query: %s" % query)
if len(args) > 0:
+ try:
log.msg("TWISTAR args: %s" % ",".join(args))
+ except Exception as e:
+ pass
elif len(kwargs) > 0:
log.msg("TWISTAR kargs: %s" % str(kwargs))
How would I fix this problem permanently? how would I edit the base class using oop? I don't want to run my own fork of the code! (what i am currently doing )
okay, I have traced it multiple times, the thing works fine in version 1.5, not in version 2.
I checked the select
function. it's turning args
to a list, log
when used to log the args fails because of the argument being a list instead of string objects. note the argument itself is a tuple, but and instead of having multiple values to be joined, it has one list as it's first argument.
I don't know how it passes the tests, but it shouldn't! :) it's easy to fix for my case, but, this should be thought of and handled properly.
I just added a *
to log function!:)
def log(self, query, args, kwargs):
"""
Log the query and any args or kwargs using C{twisted.python.log.msg} if
C{InteractionBase.LOG} is True.
"""
if not InteractionBase.LOG:
return
log.msg("TWISTAR query: %s" % query)
if len(args) > 0:
if isinstance(args[0], list):
log.msg("TWISTAR args: %s" % ",".join(*args))
else:
log.msg("TWISTAR args: %s" % ",".join(args))
elif len(kwargs) > 0:
log.msg("TWISTAR kargs: %s" % str(kwargs))