Skip to content

Fix ASTM import crashing on a sender with null components - #3047

Open
xispa wants to merge 4 commits into
2.xfrom
fix/astm-sender-null-components
Open

xispa wants to merge 4 commits into
2.xfrom
fix/astm-sender-null-components

Conversation

@xispa

@xispa xispa commented Oct 7, 2026

Copy link
Copy Markdown
Member

Description of the issue/feature this PR addresses

ASTMImporter.get_sender() assumes the (H)eader is present and that each of its three sender components is a string. Neither holds on the wire: ASTM transmits a component the analyzer did not fill as null, and a message can arrive with no header at all.

Every caller then breaks, including one inside this module. get_sender() returning None makes get_instrument_name() and its two siblings raise TypeError: 'NoneType' object is not subscriptable, since they index into the result. A null component makes the AutoImportLog fail to be written:

# importer.py, ASTMImporter.log()
self._importlog.setInterface(", ".join(self.get_sender()))
# TypeError: sequence item 0: expected string, NoneType found

So the message is lost and no log entry records why.

Current behavior before PR

header = self.get_header()
if not header:
    return None
sender = header.get("sender", {})
name = sender.get("name", "")
...

None for a headerless message, and dict.get with a default does not help for a null component: the key is there, holding None, so the default is never reached.

Desired behavior after PR is merged

get_sender() always returns three strings, with surrounding whitespace dropped. Analyzers pad these fields to a fixed width and the Instrument they have to match is configured without the padding, so an unstripped sender silently fails to resolve.

--
I confirm I have tested this PR thoroughly and coded it according to PEP8
and Plone's Python styleguide standards.

@xispa xispa added the Bug 🐞 Something is broken label Oct 7, 2026
@xispa
xispa requested a review from ramonski October 7, 2026 12:53

@ramonski ramonski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Only a small thing while we're already at this code.

header = self.get_header() or {}
sender = header.get("sender") or {}
keys = ("name", "serial", "version")
return tuple([(sender.get(key) or "").strip() for key in keys])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. One small thing in log() while we are at it: with the empty strings we now get an interface like GeneXpert, , for every analyzer that does not send a serial or a version. Could we skip the empty ones there?

sender = filter(None, self.get_sender())
self._importlog.setInterface(", ".join(sender))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug 🐞 Something is broken

Development

Successfully merging this pull request may close these issues.

2 participants