Skip to content

Propagate known request identity on ModbusIOException - #2993

Merged
janiversen merged 4 commits into
pymodbus-dev:devfrom
sankalpsthakur:fix/modbus-io-exception-identity-everywhere
Jul 28, 2026
Merged

Propagate known request identity on ModbusIOException#2993
janiversen merged 4 commits into
pymodbus-dev:devfrom
sankalpsthakur:fix/modbus-io-exception-identity-everywhere

Conversation

@sankalpsthakur

@sankalpsthakur sankalpsthakur commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #2992 / review note from @janiversen: attach known identity on ModbusIOException where transaction id and/or function code are already known.

Client execute paths (TransactionManager.sync_execute / execute):

  • Helper _io_exception_from_request attaches function_code, transaction_id, dev_id on timeouts, cancel, and device/TID mismatches.

Wire-path payload decode (review fix — previous register kwargs were dead):

Server exception path residuals from #2992 review:

  • Use exc.fcode when payload decode supplied it; otherwise 0x00 for noise/unknown FC.
  • Forward callback addr on server_send so UDP peers receive the exception (was hardcoded 0 while last_addr is cleared).

Also: ModbusPDU invalid device id carries constructor transaction_id / dev_id.

Validation

pytest test/transaction/test_transaction.py
pytest test/server/test_requesthandler.py
pytest test/framer/test_extras.py
pytest test/client/test_client_faulty_response.py
pytest test/pdu/test_register_read_messages.py test/pdu/test_pdu.py
# 538 passed (combined related suite)
zuban check pymodbus  # clean
ruff check  # clean

AI/LLM disclosure

  • AI coding tools (including Grok and/or Codex agent-assisted editing) were used to help draft or modify code and this PR description.
  • I reviewed the complete change, understand the reasoning, and ran the reported local tests before submitting.
  • This submission is original work of authorship under the project CLA / contributor terms; AI output was not pasted unreviewed.

After pymodbus-dev#2992, attach function_code, transaction_id, and dev_id wherever
the outstanding request (or PDU) already knows them: client execute
timeouts/mismatches, register decode failures, and invalid device id.

Suggested in review of pymodbus-dev#2992.

Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>
Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>
Critical review of pymodbus-dev#2992/pymodbus-dev#2993 found register_message identity was dead
because DecodePDU swallowed ModbusIOException. Re-raise payload decode
errors, enrich framing tid/dev_id in the framer, use known fcode on the
server exception response when present, and forward the UDP peer addr.

Also lean the helper docstring, drop a private-method unit test, and
assert identity through handleFrame + sync execute paths.

Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>

@janiversen janiversen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Mainly a problem with comments, please remove.

And a couple of changes.

Ps. I have not reviewed the tests.

Comment thread pymodbus/framer/base.py Outdated
try:
pdu = self.decoder.decode(frame_data)
except ModbusIOException as exc:
# Framing ids are authoritative; payload decode never has them yet.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove comments, we have few comments in the code, as the code is self documenting (and comments tend not to be maintained).

Comment thread pymodbus/framer/base.py Outdated
exc.dev_id = dev_id
raise
if pdu is None:
# Unknown/garbage FC: do not invent function_code from noise (#2990).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

no need for comment.

Comment thread pymodbus/pdu/decoders.py Outdated
str(pdu),
)
return pdu
except ModbusIOException:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is wrong, it is already caught as ModbusException.

Comment thread pymodbus/pdu/decoders.py Outdated
)
return pdu
except ModbusIOException:
# Payload decode already attached known identity (e.g. function_code).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

comment.

Comment thread pymodbus/pdu/register_message.py Outdated
"""Decode a register response packet."""
self.registers = []
if (data_len := int(data[0])) >= len(data):
# function_code is the class/request FC; framing tid/dev_id are filled

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Comment.

Comment thread pymodbus/server/requesthandler.py Outdated
# is cleared before framing runs, so identity comes from the framer
# exception attributes when available. Use function code 0x00 rather
# than a hardcoded unrelated value (was 40 / 0x28) — see #2990.
# Undecodable / corrupt PDUs land here. last_pdu is cleared before

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Comment.

@janiversen

Copy link
Copy Markdown
Collaborator

Tests are ok.

Remove narrative comments per maintainer style. Drop the DecodePDU
ModbusIOException re-raise (already covered by ModbusException). Keep
framing identity on the None path and client request identity helper.

Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>
@sankalpsthakur

Copy link
Copy Markdown
Contributor Author

Addressed in a5280f1 — removed the narrative comments and dropped the DecodePDU ModbusIOException re-raise (already covered by ModbusException).

@janiversen janiversen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, thanks

@janiversen
janiversen merged commit f889e74 into pymodbus-dev:dev Jul 28, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants