Unshunt

When errors occur while processing email messages, the messages will end up in the shunt queue. The unshunt command allows system administrators to manage the shunt queue.

>>> from mailman.commands.cli_unshunt import Unshunt
>>> command = Unshunt()

>>> class FakeArgs:
...     discard = False

Let’s say there is a message in the shunt queue.

>>> msg = message_from_string("""\
... From: aperson@example.com
... To: test@example.com
... Subject: A broken message
... Message-ID: <aardvark>
...
... """)

>>> shuntq = config.switchboards['shunt']
>>> len(list(shuntq.files))
0
>>> base_name = shuntq.enqueue(msg, {})
>>> len(list(shuntq.files))
1

The unshunt command by default moves the message back to the incoming queue.

>>> inq = config.switchboards['in']
>>> len(list(inq.files))
0

>>> command.process(FakeArgs)

>>> from mailman.testing.helpers import get_queue_messages
>>> items = get_queue_messages('in')
>>> len(items)
1
>>> print(items[0].msg.as_string())
From: aperson@example.com
To: test@example.com
Subject: A broken message
Message-ID: <aardvark>

unshunt moves all shunt queue messages.

>>> msg = message_from_string("""\
... From: aperson@example.com
... To: test@example.com
... Subject: A broken message
... Message-ID: <badgers>
...
... """)
>>> base_name = shuntq.enqueue(msg, {})

>>> msg = message_from_string("""\
... From: aperson@example.com
... To: test@example.com
... Subject: A broken message
... Message-ID: <crow>
...
... """)
>>> base_name = shuntq.enqueue(msg, {})

>>> len(list(shuntq.files))
2

>>> command.process(FakeArgs)
>>> items = get_queue_messages('in')
>>> len(items)
2

>>> sorted(item.msg['message-id'] for item in items)
['<badgers>', '<crow>']

Return to the original queue

While the messages in the shunt queue are generally returned to the incoming queue, if the error occurred while the message was being processed from a different queue, it will be returned to the queue it came from.

>>> msg = message_from_string("""\
... From: aperson@example.com
... To: test@example.com
... Subject: A broken message
... Message-ID: <dingo>
...
... """)

The queue that the message comes from is in message metadata.

>>> base_name = shuntq.enqueue(msg, {}, whichq='bounces')

>>> len(list(shuntq.files))
1
>>> len(list(config.switchboards['bounces'].files))
0

The message is automatically re-queued to the bounces queue.

>>> command.process(FakeArgs)
>>> len(list(shuntq.files))
0
>>> items = get_queue_messages('bounces')
>>> len(items)
1

>>> print(items[0].msg.as_string())
From: aperson@example.com
To: test@example.com
Subject: A broken message
Message-ID: <dingo>

Discarding all shunted messages

If you don’t care about the shunted messages, just discard them.

>>> msg = message_from_string("""\
... From: aperson@example.com
... To: test@example.com
... Subject: A broken message
... Message-ID: <elephant>
...
... """)
>>> base_name = shuntq.enqueue(msg, {})

>>> FakeArgs.discard = True
>>> command.process(FakeArgs)

The messages are now gone.

>>> items = get_queue_messages('in')
>>> len(items)
0