Opened 3 weeks ago

Closed 3 weeks ago

#9335 defect closed fixed (fixed)

PostfixTCPMapServer raises exception handling error in python 3

Reported by: Albert Koch Owned by: Craig Rodrigues <rodrigc@…>
Priority: normal Milestone: Python-3.x
Component: core Keywords:
Cc: Branch:
Author:

Description

When using the PostfixTCPMapServer, the server raises an exception when handling an exception raised by its factory get method in python 3. The server should send a 400 code to the client. This issue was not observed in python 2.

Code example to reproduce:

from twisted.protocols.postfix import PostfixTCPMapServer

# Factory that raises an error on key lookup
class TestFactory:
    def get(self, key):
        raise Exception('This is a test error')

# Transport that should receive result
class TestTransport:
    def write(self, value):
        assert(value == b'400 This is a test error\n')

# Setup Server
server = PostfixTCPMapServer()
server.factory = TestFactory()
server.transport = TestTransport()

# Run test
server.lineReceived('get example')

This runs fine under python 2.7, but fails under python 3.6:

Unhandled Error
Traceback (most recent call last):
  File "test.py", line 20, in <module>
    server.lineReceived('get example')
  File "/usr/local/lib/python3.6/site-packages/twisted/protocols/postfix.py", line 84, in lineReceived
    f(params)
  File "/usr/local/lib/python3.6/site-packages/twisted/protocols/postfix.py", line 96, in do_get
    d.addCallbacks(self._cbGot, self._cbNot)
  File "/usr/local/lib/python3.6/site-packages/twisted/internet/defer.py", line 310, in addCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "/usr/local/lib/python3.6/site-packages/twisted/internet/defer.py", line 653, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/usr/local/lib/python3.6/site-packages/twisted/protocols/postfix.py", line 102, in _cbNot
    self.sendCode(400, fail.getErrorMessage())
  File "/usr/local/lib/python3.6/site-packages/twisted/protocols/postfix.py", line 67, in sendCode
    self.sendLine(intToBytes(code) + b' ' + message)
builtins.TypeError: can't concat str to bytes

Packages installed:

attrs==17.3.0
Automat==0.6.0
constantly==15.1.0
hyperlink==17.3.1
incremental==17.5.0
six==1.11.0
Twisted==17.9.0
zope.interface==4.4.3

Change History (7)

comment:1 Changed 3 weeks ago by Craig Rodrigues

Resolution: invalid
Status: newclosed

Your code example is wrong. This line:

# Run test
server.lineReceived('get example')

should be:

# Run test
server.lineReceived(b'get example')

because lineReceived must take bytes, not unicode. Remember, by default, string literals are unicode on Python 3, but bytes on Python 2.

comment:2 Changed 3 weeks ago by Craig Rodrigues

Resolution: invalid
Status: closedreopened

comment:3 Changed 3 weeks ago by Craig Rodrigues

While your code example is wrong, you found some legitimate errors in this code, so I'm reopening.

comment:4 Changed 3 weeks ago by Craig Rodrigues

Milestone: Python-3.x

comment:5 Changed 3 weeks ago by Craig Rodrigues

Keywords: review added

comment:7 Changed 3 weeks ago by Craig Rodrigues <rodrigc@…>

Owner: set to Craig Rodrigues <rodrigc@…>
Resolution: fixed
Status: reopenedclosed

In 03dcdfb:

Merge pull request #930 from twisted/9335-rodrigc-postfix-py3

Author: rodrigc
Reviewer: albertkoch
Fixes: ticket:9335

Fix postfix on Python 3

Note: See TracTickets for help on using tickets.