Skip to content

Commit

Permalink
Pr fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TamarZanzouri authored Feb 16, 2024
1 parent f2978c7 commit 18d99a7
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 4 deletions.
10 changes: 10 additions & 0 deletions robot-server/robot_server/errors/error_mappers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Map errors to Exceptions."""
from opentrons_shared_data.errors import EnumeratedError, PythonException


def map_unexpected_error(error: BaseException) -> EnumeratedError:
"""Map an unhandled Exception to a known exception."""
if isinstance(error, EnumeratedError):
return error
else:
return PythonException(error)
33 changes: 29 additions & 4 deletions robot-server/robot_server/protocols/protocol_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
import logging

from opentrons import protocol_runner
from opentrons.protocol_engine.errors import ErrorOccurrence
import opentrons.util.helpers as datetime_helper

import robot_server.errors.error_mappers as em

from .protocol_store import ProtocolResource
from .analysis_store import AnalysisStore


log = logging.getLogger(__name__)


Expand All @@ -30,9 +33,31 @@ async def analyze(
robot_type=protocol_resource.source.robot_type,
protocol_config=protocol_resource.source.config,
)
result = await runner.run(
protocol_source=protocol_resource.source, deck_configuration=[]
)
try:
result = await runner.run(
protocol_source=protocol_resource.source, deck_configuration=[]
)
except BaseException as error:
internal_error = em.map_unexpected_error(error=error)
await self._analysis_store.update(
analysis_id=analysis_id,
robot_type=protocol_resource.source.robot_type,
commands=[],
labware=[],
modules=[],
pipettes=[],
errors=[
ErrorOccurrence.from_failed(
# TODO(tz, 2-15-24): replace with a different error type
# when we are able to support different errors.
id="internal-error",
createdAt=datetime_helper.utc_now(),
error=internal_error,
)
],
liquids=[],
)
return

log.info(f'Completed analysis "{analysis_id}".')

Expand Down
99 changes: 99 additions & 0 deletions robot-server/tests/protocols/test_protocol_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,30 @@
)
import opentrons.protocol_runner as protocol_runner
from opentrons.protocol_reader import ProtocolSource, JsonProtocolConfig
import opentrons.util.helpers as datetime_helper

from robot_server.protocols.analysis_store import AnalysisStore
from robot_server.protocols.protocol_store import ProtocolResource
from robot_server.protocols.protocol_analyzer import ProtocolAnalyzer
import robot_server.errors.error_mappers as em

from opentrons_shared_data.errors import EnumeratedError, ErrorCodes


@pytest.fixture(autouse=True)
def patch_mock_map_unexpected_error(
decoy: Decoy, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Replace map_unexpected_error with a mock."""
mock_map_unexpected_error = decoy.mock(func=em.map_unexpected_error)
monkeypatch.setattr(em, "map_unexpected_error", mock_map_unexpected_error)


@pytest.fixture(autouse=True)
def patch_mock_get_utc_datetime(decoy: Decoy, monkeypatch: pytest.MonkeyPatch) -> None:
"""Replace utc_now with a mock."""
mock_get_utc_datetime = decoy.mock(func=datetime_helper.utc_now)
monkeypatch.setattr(datetime_helper, "utc_now", mock_get_utc_datetime)


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -146,3 +166,82 @@ async def test_analyze(
liquids=[],
),
)


async def test_analyze_updates_pending_on_error(
decoy: Decoy,
analysis_store: AnalysisStore,
subject: ProtocolAnalyzer,
) -> None:
"""It should update pending analysis with an internal error."""
robot_type: RobotType = "OT-3 Standard"

protocol_resource = ProtocolResource(
protocol_id="protocol-id",
created_at=datetime(year=2021, month=1, day=1),
source=ProtocolSource(
directory=Path("/dev/null"),
main_file=Path("/dev/null/abc.json"),
config=JsonProtocolConfig(schema_version=123),
files=[],
metadata={},
robot_type=robot_type,
content_hash="abc123",
),
protocol_key="dummy-data-111",
)

raised_exception = Exception("You got me!!")

error_occurrence = pe_errors.ErrorOccurrence.construct(
id="internal-error",
createdAt=datetime(year=2023, month=3, day=3),
errorType="EnumeratedError",
detail="You got me!!",
)

enumerated_error = EnumeratedError(
code=ErrorCodes.GENERAL_ERROR,
message="You got me!!",
)

json_runner = decoy.mock(cls=protocol_runner.JsonRunner)

decoy.when(
await protocol_runner.create_simulating_runner(
robot_type=robot_type,
protocol_config=JsonProtocolConfig(schema_version=123),
)
).then_return(json_runner)

decoy.when(
await json_runner.run(
deck_configuration=[], protocol_source=protocol_resource.source
)
).then_raise(raised_exception)

decoy.when(em.map_unexpected_error(error=raised_exception)).then_return(
enumerated_error
)

decoy.when(datetime_helper.utc_now()).then_return(
datetime(year=2023, month=3, day=3)
)

await subject.analyze(
protocol_resource=protocol_resource,
analysis_id="analysis-id",
)

decoy.verify(
await analysis_store.update(
analysis_id="analysis-id",
robot_type=robot_type,
commands=[],
labware=[],
modules=[],
pipettes=[],
errors=[error_occurrence],
liquids=[],
),
)

0 comments on commit 18d99a7

Please sign in to comment.