From 47c2a5a9bb4215d55fd513c96fc104f4055388c3 Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Fri, 10 Apr 2026 20:50:13 +0200 Subject: [PATCH] fix: add request registration for early failures in device instructions handling --- .../bec_server/device_server/device_server.py | 16 +++++++++++++++- .../tests_device_server/test_device_server.py | 16 +++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/bec_server/bec_server/device_server/device_server.py b/bec_server/bec_server/device_server/device_server.py index 01995184c..d791d6585 100644 --- a/bec_server/bec_server/device_server/device_server.py +++ b/bec_server/bec_server/device_server/device_server.py @@ -504,6 +504,18 @@ def _get_metadata_for_alarm( metadata["scan_number"] = msg.scan_number return metadata + def _ensure_request_registered( + self, instruction: messages.DeviceInstructionMessage | None + ) -> None: + """Register a placeholder request so early failures can still resolve.""" + if instruction is None: + return + instr_id = instruction.metadata.get("device_instr_id") + if instr_id is None: + return + if self.requests_handler.get_request(instr_id) is None: + self.requests_handler.add_request(instruction, num_status_objects=0) + def handle_device_instructions(self, msg: messages.DeviceInstructionMessage) -> None: """Parse a device instruction message and handle the requested action. Action types are set, read, rpc, kickoff or trigger. @@ -553,6 +565,7 @@ def handle_device_instructions(self, msg: messages.DeviceInstructionMessage) -> exception_type=limit_error.__class__.__name__, device=self.get_device_from_exception(limit_error), ) + self._ensure_request_registered(instructions) self.requests_handler.set_finished( instructions.metadata["device_instr_id"], success=False, error_info=error_info ) @@ -567,8 +580,9 @@ def handle_device_instructions(self, msg: messages.DeviceInstructionMessage) -> exception_type=exc.__class__.__name__, device=self.get_device_from_exception(exc), ) + self._ensure_request_registered(instructions) if action == "rpc": - self.rpc_handler._send_rpc_exception(exc, instructions) + self.rpc_handler.send_rpc_exception(exc, instructions) else: logger.error(content) self.requests_handler.set_finished( diff --git a/bec_server/tests/tests_device_server/test_device_server.py b/bec_server/tests/tests_device_server/test_device_server.py index aa9ca786c..f443aff19 100644 --- a/bec_server/tests/tests_device_server/test_device_server.py +++ b/bec_server/tests/tests_device_server/test_device_server.py @@ -347,10 +347,20 @@ def test_handle_device_instruction_disabled_device(device_server_mock, instructi """ device_server = device_server_mock with mock.patch.object(device_server, "assert_device_is_enabled", side_effect=RuntimeError): - with mock.patch.object(device_server.requests_handler, "set_finished") as set_finished_mock: + with mock.patch.object(device_server.connector, "send") as send_mock: device_server.handle_device_instructions(instructions) - set_finished_mock.assert_called_once_with( - instructions.metadata["device_instr_id"], success=False, error_info=ANY + assert send_mock.call_count == 2 + pending_msg = send_mock.call_args_list[0].args[1] + error_msg = send_mock.call_args_list[1].args[1] + + assert pending_msg.instruction_id == instructions.metadata["device_instr_id"] + assert pending_msg.status == "running" + assert error_msg.instruction_id == instructions.metadata["device_instr_id"] + assert error_msg.status == "error" + assert error_msg.error_info is not None + assert ( + device_server.requests_handler.get_request(instructions.metadata["device_instr_id"]) + is None )