Skip to content

Fix exception error message for decoding response #2618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 28, 2025

Conversation

Szewcson
Copy link
Contributor

When decoding exception frame Error message is showing always exception code as 0. Also in error message I think showing Exception code in human readable format will be more helpful, as well as showing failing FC instead FC with exception bit set.

@Szewcson Szewcson force-pushed the exception_error_msg_fix branch from ce98e31 to 9cbab36 Compare March 28, 2025 08:49
Signed-off-by: Adam Szewczyk <a.szewczyk@cthings.co>
@Szewcson Szewcson force-pushed the exception_error_msg_fix branch from 9cbab36 to 3c3afcc Compare March 28, 2025 08:50
@Szewcson
Copy link
Contributor Author

Also maybe exception code and function code should be added to str?

Copy link
Collaborator

@janiversen janiversen left a comment

Choose a reason for hiding this comment

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

The idea is good, but there are a number of comments.

@@ -118,6 +118,20 @@ class ExceptionResponse(ModbusPDU):
GATEWAY_PATH_UNAVIABLE = 0x0A
GATEWAY_NO_RESPONSE = 0x0B

exception_code_dict = {
0x00: "None",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use the constants defined above, to avoid mismatch between constant and value.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a constant meaning the name should be capitalized

@@ -102,7 +102,7 @@ def decode(self, frame: bytes) -> base.ModbusPDU | None:
"""Decode a frame."""
try:
if (function_code := int(frame[0])) > 0x80:
pdu_exp = base.ExceptionResponse(function_code & 0x7F)
pdu_exp = base.ExceptionResponse(function_code & 0x7F, int(frame[1]))
Copy link
Collaborator

Choose a reason for hiding this comment

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

please do not convert to int, if a conversion is needed it should be done where needed.

@@ -137,3 +152,4 @@ def encode(self) -> bytes:
def decode(self, data: bytes) -> None:
"""Decode a modbus exception response."""
self.exception_code = int(data[0])
self.exception_name = self.exception_code_dict.get(self.exception_code, f"Unknown Exception value: {self.exception_code}")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure what this does, it really seems not needed.

@@ -128,7 +142,8 @@ def __init__(
super().__init__(transaction_id=transaction, dev_id=device_id)
self.function_code = function_code | 0x80
self.exception_code = exception_code
Log.error(f"Exception response {self.function_code} / {self.exception_code}")
self.exception_name = self.exception_code_dict.get(self.exception_code, f"Unknown Exception value: {self.exception_code}")
Copy link
Collaborator

Choose a reason for hiding this comment

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

no need to make an object variable, remove self.

@@ -128,7 +142,8 @@ def __init__(
super().__init__(transaction_id=transaction, dev_id=device_id)
self.function_code = function_code | 0x80
self.exception_code = exception_code
Log.error(f"Exception response {self.function_code} / {self.exception_code}")
self.exception_name = self.exception_code_dict.get(self.exception_code, f"Unknown Exception value: {self.exception_code}")
Log.error(f"Exception response FC{self.function_code & 0x7F} / {self.exception_name}")
Copy link
Collaborator

Choose a reason for hiding this comment

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

no need to add 0x7f just use the function_code parameter.

Just showing the name, makes it more difficult for log parsers so the code should still be presented.

Showing the exception name makes sense for people who do not know the modbus standard, but the same people to not know the function codes either....so it would be better to either use names for both or not at all.

Copy link
Collaborator

@janiversen janiversen Mar 28, 2025

Choose a reason for hiding this comment

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

in general instead of logging, it would be better as __str__ allowing the app to do what it want.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, so which approach here will be the best?

Copy link
Collaborator

Choose a reason for hiding this comment

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

make __str__

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And with the log?

Copy link
Collaborator

@janiversen janiversen Mar 28, 2025

Choose a reason for hiding this comment

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

no, pymodbus normally do not log responses....apart from that in the eyes of pymodbus this is not an error.

But I am flexible with that.....

@Szewcson Szewcson force-pushed the exception_error_msg_fix branch from f7baa94 to 9f65a77 Compare March 28, 2025 10:39

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Signed-off-by: szewcu <szewcson@gmail.com>
@Szewcson Szewcson force-pushed the exception_error_msg_fix branch from 9f65a77 to d24dddf Compare March 28, 2025 10:41
@Szewcson
Copy link
Contributor Author

But this log was there probably for opposite situation - generation of the exception. Maybe we need some flag then.

@janiversen
Copy link
Collaborator

the generation of the exception is used in the server.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Signed-off-by: szewcu <szewcson@gmail.com>
@Szewcson Szewcson requested a review from janiversen March 28, 2025 14:03
Signed-off-by: szewcu <szewcson@gmail.com>
@Szewcson Szewcson requested a review from janiversen March 28, 2025 14:15
Copy link
Collaborator

@janiversen janiversen left a comment

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 0b94011 into pymodbus-dev:dev Mar 28, 2025
1 check 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.

None yet

2 participants