crossbario / autobahn-python

WebSocket and WAMP in Python for Twisted and asyncio
https://crossbar.io/autobahn
MIT License
2.48k stars 770 forks source link

Gracefully handle wrong parameter number to WAMP procedures #1122

Closed oberstet closed 5 years ago

oberstet commented 5 years ago

We should gracefully handle (or allow the app to handle) the situation where a WAMP procedure is called with wrong number of positional arguments:

2019-02-22T15:31:39+0100 [XBRMrktMkr  24056] Traceback (most recent call last):
  File "/home/oberstet/cpy372_7/lib/python3.7/site-packages/autobahn/wamp/websocket.py", line 95, in onMessage
    self._session.onMessage(msg)
  File "/home/oberstet/cpy372_7/lib/python3.7/site-packages/autobahn/wamp/protocol.py", line 939, in onMessage
    on_reply = txaio.as_future(endpoint.fn, *invoke_args, **invoke_kwargs)
  File "/home/oberstet/cpy372_7/lib/python3.7/site-packages/txaio/tx.py", line 428, in as_future
    return ensureDeferred(fun(*args, **kwargs))
TypeError: buy_key() missing 1 required positional argument: 'signature'

2019-02-22T15:31:39+0100 [XBRMrktMkr  24056] dropping connection to peer tcp4:127.0.0.1:8081 with abort=True: I dropped the WebSocket TCP connection: WAMP Internal Error (buy_key() missing 1 required positional argument: 'signature')
2019-02-22T15:31:39+0100 [XBRMrktMkr  24056] session leaving 'wamp.close.transport_lost'
2019-02-22T15:31:39+0100 [XBRMrktMkr  24056] wamp.close.transport_lost: 
2019-02-22T15:31:39+0100 [XBRMrktMkr  24056] >>> Maker session DETACHED from data market (details=CloseDetails(reason=<wamp.close.transport_lost>, message='WAMP transport was lost without closing the session before'))
2019-02-22T15:31:39+0100 [XBRMrktMkr  24056] Stopping factory <autobahn.twisted.websocket.WampWebSocketClientFactory object at 0x7f657992bba8>
2019-02-22T15:31:41+0100 [XBRMrktMkr  24056] connecting once using transport type "websocket" over endpoint "tcp"
2019-02-22T15:31:41+0100 [XBRMrktMkr  24056] Starting factory <autobahn.twisted.websocket.WampWebSocketClientFactory object at 0x7f6575397d68>
2019-02-22T15:31:41+0100 [XBRMrktMkr  24056] >>> Maker session ATTACHED to data market (details=SessionDetails(realm=<realm1>, session=6500367308499916, authid=<HMQY-5EFY-5GEV-LUXM-P3P6-H5VY>, authrole=<xbrmm>, authmethod=anonymous, authprovider=static, authextra={'x_cb_node_id': None, 'x_cb_peer': 'tcp4:127.0.0.1:46350', 'x_cb_pid': 24043}, resumed=None, resumable=None, resume_token=None)) on thread 140074355159168
2019-02-22T15:31:41+0100 [XBRMrktMkr  24056] Registered 8 procedures
oberstet commented 5 years ago
(cpy372_1) oberstet@intel-nuci7:~$ python
Python 3.7.2 (default, Feb 25 2019, 08:26:41) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import txaio
>>> txaio.use_twisted()
>>> def foo(a, b):
...     return a + b
... 
>>> args = [1, 2]
>>> txaio.as_future(foo, *args)
<Deferred at 0x7f9c304746d8 current result: 3>
>>> args = [1, 2, 3]
>>> txaio.as_future(foo, *args)
<Deferred at 0x7f9c30474f98 current result: <twisted.python.failure.Failure builtins.TypeError: foo() takes 2 positional arguments but 3 were given>>
>>> def moo(a, b, details=None):
...     return a + b
... 
>>> txaio.as_future(moo, *args)
Unhandled error in Deferred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

  File "/home/oberstet/cpy372_1/lib/python3.7/site-packages/txaio/tx.py", line 429, in as_future
    return maybeDeferred(fun, *args, **kwargs)
--- <exception caught here> ---
  File "/home/oberstet/cpy372_1/lib/python3.7/site-packages/twisted/internet/defer.py", line 151, in maybeDeferred
    result = f(*args, **kw)
builtins.TypeError: foo() takes 2 positional arguments but 3 were given

<Deferred at 0x7f9c304746d8 current result: 3>
>>> 
oberstet commented 5 years ago

^ note the 2nd fail is behaving differently from the 1st

meejah commented 5 years ago

Oh, so this is just nuking the connection on TypeError instead of sending an error WAMP message back?

oberstet commented 5 years ago

@meejah yes, that's what I suspect. we should probably have test cases with all thinkable variants (eg as above 2, and more), and make sure that all cases ultimately result in an ERROR message being sent as call result - which then materializes as an ApplicationError raised on the caller side.

meejah commented 5 years ago

Weird, I see different txaio behavior than above:

In [7]: txaio.as_future(foo, *(1, 2))
Out[7]: <Deferred at 0x7f16ce7d55c0 current result: 3>

In [8]: txaio.as_future(foo, *(1, 2, 3))
Out[8]: <Deferred at 0x7f16ce7d5898 current result: <twisted.python.failure.Failure builtins.TypeError: foo() takes 2 positional arguments but 3 were given>>
meejah commented 5 years ago

Similar to above with asyncio instead. This is on cpython 3.6.3

meejah commented 5 years ago

txaio 18.8.1

meejah commented 5 years ago

I can't repeat the "second failure" above in the interactive session (neither 3.6.3 or 3.7.3):

Python 3.7.3 (default, May  2 2019, 12:54:42)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import txaio

In [2]: txaio.use_twisted()

In [3]: def foo(a, b):
   ...:     return a + b
   ...: 

In [4]: args = [1, 2]

In [5]: txaio.as_future(foo, *args)
Out[5]: <Deferred at 0x7fd23cef9940 current result: 3>

In [6]: args = [1, 2, 3]

In [7]: txaio.as_future(foo, *args)
Out[7]: <Deferred at 0x7fd23cefdda0 current result: <twisted.python.failure.Failure builtins.TypeError: foo() takes 2 positional arguments but 3 were given>>

In [8]: def moo(a, b, details=None):
   ...:     return a + b
   ...: 

In [9]: txaio.as_future(moo, *args)
Out[9]: <Deferred at 0x7fd23ce9ab70 current result: 3>

I also added an integration test-case for this, which also passes ... so I'm closing this, unless there's another way to repeat the problem?