I have a Twisted ServerFactory, which I started with listenTCP. How do I start a task that is a function of that factory?
I tried:
if __name__ == "__main__":
factory = MyFactory()
reactor.listenTCP(555558, factory)
reactor.connectTCP("127.0.0.1", 55555, MyConnector(factory))
sanitizing = task.LoopingCall(factory.sanitize())
sanitizing.start(3, False)
reactor.run()
But that throws an error:
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1192, in run self.mainLoop()
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1201, in mainLoop
self.runUntilCurrent()
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 824, in runUntilCurrent
call.func(*call.args, **call.kw)
File "/usr/lib/python2.7/dist-packages/twisted/internet/task.py", line 218, in __call__
d = defer.maybeDeferred(self.f, *self.a, **self.kw)
--- <exception caught here> ---
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 139, in maybeDeferred
result = f(*args, **kw)
exceptions.TypeError: 'NoneType' object is not callable
The factory is actually listening, so I don't understand why it is NoneType.
In Python, name() is the syntax to call an object (usually a function or method). By extension, name(another_name()) is how you call an object (referenced by the name another_name) and then pass the return value of that call to another object (referenced by the name name).
To apply this to your example, LoopingCall(factory.sanitize()) is how you call factory.sanitize and pass the return value to LoopingCall.
This is most likely not what you meant. Instead, you probably meant to pass factory.sanitize as an argument to LoopingCall. This is what you would need to do if you wanted LoopingCall to call factory.sanitize periodically, anyway. I'm just guessing this is what you want - you didn't actually explicitly say what you want in your question. :)
Related
My Code
from twisted.internet import task, reactor
def stuff():
print('Hello, world!')
scheduler = task.LoopingCall(stuff())
scheduler.start(10)
reactor.run()
This is the Error I am getting
Hello, world! Unhandled error in Deferred:
Traceback (most recent call last): File "C:\Users\Usama
fiaz\AppData\Local\Programs\Python\Python39\lib\site-packages\twisted\internet\base.py",
line 1315, in run
self.mainLoop() File "C:\Users\Usama fiaz\AppData\Local\Programs\Python\Python39\lib\site-packages\twisted\internet\base.py",
line 1325, in mainLoop
reactorBaseSelf.runUntilCurrent() File "C:\Users\Usama fiaz\AppData\Local\Programs\Python\Python39\lib\site-packages\twisted\internet\base.py",
line 991, in runUntilCurrent
call.func(*call.args, **call.kw) File "C:\Users\Usama fiaz\AppData\Local\Programs\Python\Python39\lib\site-packages\twisted\internet\task.py",
line 251, in call
d = maybeDeferred(self.f, *self.a, **self.kw)
--- --- File "C:\Users\Usama fiaz\AppData\Local\Programs\Python\Python39\lib\site-packages\twisted\internet\defer.py",
line 190, in maybeDeferred
result = f(*args, **kwargs) builtins.TypeError: 'NoneType' object is not callable
Per the API documentation, LoopingCall.__init__ accepts a callable parameter f as its first argument.
In your example:
from twisted.internet import task, reactor
def stuff():
print('Hello, world!')
scheduler = task.LoopingCall(stuff())
scheduler.start(10)
reactor.run()
the value being passed for f is the result of evaluating stuff() - in other words, it is the return value of the stuff function. stuff implicitly returns None so your LoopingCall construction is equivalent to:
scheduler = task.LoopingCall(stuff())
Then, when you start the loop with LoopingCall.start you don't attach any error handlers. When LoopingCall tries to call None an exception is raised. Since there are no error handlers attached, the exception is reported as an "Unhandled error in Deferred" and logged for you.
If you want the LoopingCall to call stuff at the defined interval, pass stuff to it (instead of None). If you want to deal with errors in your loop, attach an error handler to the Deferred returned by LoopingCall.start.
I am trying to to handle errors which may be thrown by psycopg2, so I imported the errors the pipeline was facing and got a weird error when I ran the spider.
pipelines.py
from psycopg2.errors import InvalidTextRepresentation
from psycopg2.errors import InFailedSqlTransaction
...
try:
self.cursor.execute(
"""INSERT INTO links (url,price) VALUES (%s, %s)""",
(
item["productURL"],
item["price"]
))
except InvalidTextRepresentation, InFailedSqlTransaction:
pass
I got this error directly and the spider didn't run
Unhandled error in Deferred:
Temporarily disabling observer LegacyLogObserverWrapper(<bound method PythonLoggingObserver.emit of <twisted.python.log.PythonLoggingObserver object at 0x7ff963789e80>>) due to exception: [Failure instance: Traceback: <class 'TypeError'>: _findCaller() takes from 1 to 2 positional arguments but 3 were given
/usr/lib/python3/dist-packages/twisted/internet/defer.py:953:__del__
/usr/lib/python3/dist-packages/twisted/logger/_logger.py:270:critical
/usr/lib/python3/dist-packages/twisted/logger/_logger.py:144:emit
--- <exception caught here> ---
/usr/lib/python3/dist-packages/twisted/logger/_observer.py:131:__call__
/usr/lib/python3/dist-packages/twisted/logger/_legacy.py:93:__call__
/usr/lib/python3/dist-packages/twisted/python/log.py:595:emit
/usr/lib/python3/dist-packages/twisted/logger/_legacy.py:154:publishToNewObserver
/usr/lib/python3/dist-packages/twisted/logger/_stdlib.py:115:__call__
/usr/lib/python3.8/logging/__init__.py:1500:log
/usr/lib/python3.8/logging/__init__.py:1565:_log
]
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/twisted/internet/defer.py", line 953, in __del__
log.critical("Unhandled error in Deferred:",
File "/usr/lib/python3/dist-packages/twisted/logger/_logger.py", line 270, in critical
self.emit(LogLevel.critical, format, **kwargs)
File "/usr/lib/python3/dist-packages/twisted/logger/_logger.py", line 144, in emit
self.observer(event)
--- <exception caught here> ---
File "/usr/lib/python3/dist-packages/twisted/logger/_observer.py", line 131, in __call__
observer(event)
File "/usr/lib/python3/dist-packages/twisted/logger/_legacy.py", line 93, in __call__
self.legacyObserver(event)
File "/usr/lib/python3/dist-packages/twisted/python/log.py", line 595, in emit
_publishNew(self._newObserver, eventDict, textFromEventDict)
File "/usr/lib/python3/dist-packages/twisted/logger/_legacy.py", line 154, in publishToNewObserver
observer(eventDict)
File "/usr/lib/python3/dist-packages/twisted/logger/_stdlib.py", line 115, in __call__
self.logger.log(
File "/usr/lib/python3.8/logging/__init__.py", line 1500, in log
self._log(level, msg, args, **kwargs)
File "/usr/lib/python3.8/logging/__init__.py", line 1565, in _log
fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel)
builtins.TypeError: _findCaller() takes from 1 to 2 positional arguments but 3 were given
I changed back to except: instead of except InvalidTextRepresentation, InFailedSqlTransaction: it worked fine, Is there something I am doing wrong or is there a better to handle the errors of psycopg2
This is the error log:
[I 160308 11:09:59 web:1908] 200 GET /admin/realtime (117.93.180.216) 107.13ms
[E 160308 11:09:59 http1connection:54] Uncaught exception
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/tornado/http1connection.py", line 238, in _read_message
delegate.finish()
File "/usr/local/lib/python3.4/dist-packages/tornado/httpserver.py", line 290, in finish
self.delegate.finish()
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 1984, in finish
self.execute()
File "/usr/local/lib/python3.4/dist-packages/blueware-1.0.10/blueware/hooks/framework_tornado/web.py", line 480, in _bw_wrapper__RequestDispatcher_execute
future = wrapped(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 2004, in execute
**self.handler_kwargs)
File "/usr/local/lib/python3.4/dist-packages/blueware-1.0.10/blueware/hooks/framework_tornado/web.py", line 448, in _bw_wrapper_RequestHandler___init___
return wrapped(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 185, in init
self.initialize(**kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 2714, in wrapper
self.redirect(url)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 671, in redirect
self.finish()
File "/usr/local/lib/python3.4/dist-packages/blueware-1.0.10/blueware/hooks/framework_tornado/web.py", line 309, in _bw_wrapper_RequestHandler_finish_
return wrapped(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 934, in finish
self.flush(include_footers=True)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 870, in flush
for transform in self._transforms:
TypeError: 'NoneType' object is not iterable
[I 160308 11:10:00 web:1908] 200 GET /admin/order?order_type=1&order_status=1&page=0&action=allreal (49.89.27.173) 134.53ms
Can anyone tell me how to solve this problem? Thank you very much
I assume that OneAPM (blueware agent) is compatible with your python and Tornado version, however it's can be tricky.
Solution
Move self.redirect(url) from your handler initialize method to get method, like this
class MyHandler(tornado.web.RequestHandler):
def get(self):
self.redirect('/some_url')
or use RedirectHandler.
Every action that could finish request needs to be called in context of http-verb method (get, post, put and so on). The common mistake is making authetication/authorization in __init__ or initialize.
More detail
In Tornado's source there is a note about _transforms that is initialized in the constructor with None and set in_execute (oversimplifying - after headers_received).
A transform modifies the result of an HTTP request (e.g., GZip encoding).
Applications are not expected to create their own OutputTransforms
or interact with them directly; the framework chooses which transforms
(if any) to apply.
Reproduce
Sample that triggers this error. I'm including this only as a cross-check that blueware is not the cause:
import tornado.ioloop
import tornado.web
class SomeHandler(tornado.web.RequestHandler):
def initialize(self, *args, **kwargs):
url = '/some'
self.redirect(url)
# ^ this is wrong
def get(self):
# redirect should be here
self.write("Hello")
def make_app():
return tornado.web.Application([
(r"/", SomeHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
And stacktrace:
ERROR:tornado.application:Uncaught exception
Traceback (most recent call last):
File "/tmp/py3/lib/python3.4/site-packages/tornado/http1connection.py", line 238, in _read_message
delegate.finish()
File "/tmp/py3/lib/python3.4/site-packages/tornado/httpserver.py", line 289, in finish
self.delegate.finish()
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 2022, in finish
self.execute()
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 2042, in execute
**self.handler_kwargs)
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 183, in __init__
self.initialize(**kwargs)
File "test.py", line 8, in initialize
self.redirect(url)
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 666, in redirect
self.finish()
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 932, in finish
self.flush(include_footers=True)
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 868, in flush
for transform in self._transforms:
TypeError: 'NoneType' object is not iterable
I'm using Starpy to automate Asterisk. Everything works except sometimes I get one call out of 150 where Asterisk fails to originate call.
Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/starpy/manager.py", line 154, in lineReceived
self.dispatchIncoming() # does dispatch and clears cache
File "/usr/local/lib/python2.7/dist-packages/starpy/manager.py", line 242, in dispatchIncoming
callback(message)
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 362, in callback
self._startRunCallbacks(result)
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 458, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 545, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/usr/local/lib/python2.7/dist-packages/starpy/manager.py", line 348, in errorUnlessResponse
raise error.AMICommandFailure(message)
starpy.error.AMICommandFailure: {'message': 'Originate failed', 'response': 'Error', 'actionid': '53345672-2'}
Based on my research, this error occurs when the callee does not answer the call. However, I'm not convinced and looking for more details about why "origiate failed". I thought about monitoring the channel before we start dialing, but it doesn't work. Channel monitor needs to be called after the callee answers the call.
Please let me know if you have any suggestions.
Thanks.
Use tcpdump or other similar tool to see what exactly asterisk sends
After that fix that library, very likly it just have bug.
I'm using this:
from twisted.web.client import getPage
df = getPage(url) # there is some url
I'm getting the following error. Please can anyone guide me on this
ERROR:twsited:Unhandled error in Deferred:
ERROR:twsited:Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/starpy/manager.py", line 123, in lineReceived
self.dispatchIncoming() # does dispatch and clears cache
File "/usr/local/lib/python2.6/dist-packages/starpy/manager.py", line 200, in dispatchIncoming
callback( message )
File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 243, in callback
self._startRunCallbacks(result)
File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 312, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 328, in _runCallbacks
self.result = callback(self.result, *args, **kw)
File "/usr/local/lib/python2.6/dist-packages/starpy/manager.py", line 298, in errorUnlessResponse
raise error.AMICommandFailure( message )
starpy.error.AMICommandFailure: {'message': 'Channel not specified', 'response': 'Error', 'actionid': 'askme-158811948-5'}
I'm not sure this error is due to getPage() method because even when i've commented this it still give me the same error. Can anyone help. I can't figure out the reason for the error and where it is generated
The code posted is not complete. The error is not due to getPage.
From the stack trace clues, this uses AMIProtocol (line receiver) .
I guess some where you have to specify your protocol channel in AMIProtocol
setVar(self, channel, variable, value) in star.py.
This is not a twisted issue.