-
Notifications
You must be signed in to change notification settings - Fork 1k
Return 0x02 Illegal Data Address instead of 0x04 Server Device Failure #2717
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,6 +69,14 @@ def __init__(self, string=""): | |
| message = f"[No Such id] {string}" | ||
| ModbusException.__init__(self, message) | ||
|
|
||
| class NoSuchAddressException(ModbusException): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?? That it something normal, that the library should handle gracefully (and it does in the simulator datastore). Exception like e.g. NotImplementedException are there to signal the developers forgot to implement something.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How else, besides bubbling an Exception up, is the response handler supposed to know what the underlying error was? |
||
| """Error resulting from making a request for a register that does not exist.""" | ||
|
|
||
| def __init__(self, string=""): | ||
| """Initialize.""" | ||
| message = f"[No such register address] {string}" | ||
| ModbusException.__init__(self, message) | ||
|
|
||
|
|
||
| class NotImplementedException(ModbusException): | ||
| """Error resulting from not implemented function.""" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,11 @@ | |
| import asyncio | ||
| import traceback | ||
|
|
||
| from pymodbus.exceptions import ModbusIOException, NoSuchIdException | ||
| from pymodbus.exceptions import ( | ||
| ModbusIOException, | ||
| NoSuchAddressException, | ||
| NoSuchIdException, | ||
| ) | ||
| from pymodbus.logging import Log | ||
| from pymodbus.pdu.pdu import ExceptionResponse | ||
| from pymodbus.transaction import TransactionManager | ||
|
|
@@ -105,6 +109,9 @@ async def handle_request(self): | |
| if self.server.ignore_missing_devices: | ||
| return # the client will simply timeout waiting for a response | ||
| response = ExceptionResponse(self.last_pdu.function_code, ExceptionResponse.GATEWAY_NO_RESPONSE) | ||
| except NoSuchAddressException: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The request handler should really not know about the datastore...it handles requests and returns a response. |
||
| Log.error("Requested register address does not exist: {}", self.last_pdu.address) | ||
| response = ExceptionResponse(self.last_pdu.function_code, ExceptionResponse.ILLEGAL_ADDRESS) | ||
| except Exception as exc: # pylint: disable=broad-except | ||
| Log.error( | ||
| "Datastore unable to fulfill request: {}; {}", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why raise an exception, that is not the pattern we normally use....exceptions are raised when the library encounters a problem that was not covered by code.
You can just return ExceptionResponse.ILLEGAL_ADDRESS, that should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getValues(in the happy case) returns alistof values, not a fullModbusResponse.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look in simulator.py line 588, it returns a list of values or an integer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!! Returning a magic value is strange, undocumented, and causing confusing types.
Arguably
self.validate()itself should throw the Exception.