Skip to content

Commit

Permalink
Put the run into recovery mode when there's a recoverable error. Allo…
Browse files Browse the repository at this point in the history
…w exiting with `resume-from-recovery` and `stop`.
  • Loading branch information
SyntaxColoring committed Mar 19, 2024
1 parent 05c9986 commit 641fff2
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions api/src/opentrons/protocol_engine/state/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, List, Optional, Union
from typing_extensions import assert_never

from opentrons_shared_data.errors import EnumeratedError, ErrorCodes, PythonException

Expand Down Expand Up @@ -306,13 +307,25 @@ def handle_action(self, action: Action) -> None: # noqa: C901
command_id=id, failed_at=action.failed_at, error_occurrence=None
)
self._state.queued_setup_command_ids.clear()
elif (
prev_entry.command.intent == CommandIntent.PROTOCOL
or prev_entry.command.intent is None
):
if action.type == ErrorRecoveryType.WAIT_FOR_RECOVERY:
self._state.queue_status = QueueStatus.AWAITING_RECOVERY
elif action.type == ErrorRecoveryType.FAIL_RUN:
other_command_ids_to_fail = self._state.queued_command_ids
for id in other_command_ids_to_fail:
self._update_to_failed(
command_id=id,
failed_at=action.failed_at,
error_occurrence=None,
)
self._state.queued_command_ids.clear()
else:
assert_never(action.type)
else:
other_command_ids_to_fail = self._state.queued_command_ids
for id in other_command_ids_to_fail:
self._update_to_failed(
command_id=id, failed_at=action.failed_at, error_occurrence=None
)
self._state.queued_command_ids.clear()
assert_never(prev_entry.command.intent)

if self._state.running_command_id == action.command_id:
self._state.running_command_id = None
Expand All @@ -331,6 +344,9 @@ def handle_action(self, action: Action) -> None: # noqa: C901
elif isinstance(action, PauseAction):
self._state.queue_status = QueueStatus.PAUSED

elif isinstance(action, ResumeFromRecoveryAction):
self._state.queue_status = QueueStatus.RUNNING

elif isinstance(action, StopAction):
if not self._state.run_result:
self._state.queue_status = QueueStatus.PAUSED
Expand Down Expand Up @@ -377,6 +393,8 @@ def handle_action(self, action: Action) -> None: # noqa: C901
if self._config.block_on_door_open:
if action.door_state == DoorState.OPEN:
self._state.is_door_blocking = True
# todo(mm, 2024-03-19): It's unclear how the door should interact
# with error recovery (QueueStatus.AWAITING_RECOVERY).
if self._state.queue_status != QueueStatus.SETUP:
self._state.queue_status = QueueStatus.PAUSED
elif action.door_state == DoorState.CLOSED:
Expand Down Expand Up @@ -802,6 +820,11 @@ def get_status(self) -> EngineStatus:
else:
return EngineStatus.PAUSED

elif self._state.queue_status == QueueStatus.AWAITING_RECOVERY:
return EngineStatus.AWAITING_RECOVERY

# todo(mm, 2024-03-19): Does this intentionally return idle if QueueStatus is
# SETUP and we're currently a setup command?
return EngineStatus.IDLE

def get_latest_command_hash(self) -> Optional[str]:
Expand Down

0 comments on commit 641fff2

Please sign in to comment.