Skip to content

Commit ec49410

Browse files
authored
fix(app): Inject labware definitions into Error Recovery (#17248)
Closes RQA-3814
1 parent 3a46ebe commit ec49410

File tree

10 files changed

+116
-83
lines changed

10 files changed

+116
-83
lines changed

app/src/organisms/Desktop/Devices/ProtocolRun/ProtocolRunHeader/RunHeaderModalContainer/RunHeaderModalContainer.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export function RunHeaderModalContainer(
5252
runStatus={runStatus}
5353
runId={runId}
5454
unvalidatedFailedCommand={recoveryModalUtils.failedCommand}
55+
runLwDefsByUri={recoveryModalUtils.runLwDefsByUri}
5556
protocolAnalysis={robotProtocolAnalysis}
5657
/>
5758
) : null}

app/src/organisms/ErrorRecoveryFlows/__fixtures__/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const mockRecoveryContentProps: RecoveryContentProps = {
5858
byRunRecord: mockFailedCommand,
5959
byAnalysis: mockFailedCommand,
6060
},
61+
runLwDefsByUri: {} as any,
6162
errorKind: 'GENERAL_ERROR',
6263
robotType: FLEX_ROBOT_TYPE,
6364
runId: 'MOCK_RUN_ID',

app/src/organisms/ErrorRecoveryFlows/__tests__/ErrorRecoveryFlows.test.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ vi.mock('react-redux', async () => {
4545
describe('useErrorRecoveryFlows', () => {
4646
beforeEach(() => {
4747
vi.mocked(useCurrentlyRecoveringFrom).mockReturnValue('mockCommand' as any)
48+
vi.mocked(useRunLoadedLabwareDefinitionsByUri).mockReturnValue({})
4849
})
4950

5051
it('should have initial state of isERActive as false', () => {
@@ -89,12 +90,32 @@ describe('useErrorRecoveryFlows', () => {
8990
expect(result.current.failedCommand).toEqual('mockCommand')
9091
})
9192

93+
it("should return the run's labware definitions", () => {
94+
const { result } = renderHook(() =>
95+
useErrorRecoveryFlows('MOCK_ID', RUN_STATUS_RUNNING)
96+
)
97+
98+
expect(result.current.failedCommand).toEqual('mockCommand')
99+
})
100+
92101
it(`should return isERActive false if the run status is ${RUN_STATUS_STOP_REQUESTED} before seeing ${RUN_STATUS_AWAITING_RECOVERY}`, () => {
93102
const { result } = renderHook(() =>
94103
useErrorRecoveryFlows('MOCK_ID', RUN_STATUS_STOP_REQUESTED)
95104
)
96105

97-
expect(result.current.isERActive).toEqual(false)
106+
expect(result.current.runLwDefsByUri).toEqual({})
107+
})
108+
109+
it('should not return isERActive if the run labware defintions is null', () => {
110+
vi.mocked(useRunLoadedLabwareDefinitionsByUri).mockReturnValue(null)
111+
112+
const { result } = renderHook(
113+
runStatus => useErrorRecoveryFlows('MOCK_ID', runStatus),
114+
{
115+
initialProps: RUN_STATUS_AWAITING_RECOVERY,
116+
}
117+
)
118+
expect(result.current.isERActive).toBe(false)
98119
})
99120

100121
it('should set hasSeenAwaitingRecovery to true when runStatus is RUN_STATUS_AWAITING_RECOVERY', () => {
@@ -143,6 +164,7 @@ describe('ErrorRecoveryFlows', () => {
143164
unvalidatedFailedCommand: mockFailedCommand,
144165
runId: 'MOCK_RUN_ID',
145166
protocolAnalysis: null,
167+
runLwDefsByUri: {},
146168
}
147169
vi.mocked(ErrorRecoveryWizard).mockReturnValue(<div>MOCK WIZARD</div>)
148170
vi.mocked(RecoverySplash).mockReturnValue(<div>MOCK RUN PAUSED SPLASH</div>)
@@ -167,7 +189,6 @@ describe('ErrorRecoveryFlows', () => {
167189
intent: 'recovering',
168190
showTakeover: false,
169191
})
170-
vi.mocked(useRunLoadedLabwareDefinitionsByUri).mockReturnValue({})
171192
})
172193

173194
it('renders the wizard when showERWizard is true', () => {

app/src/organisms/ErrorRecoveryFlows/hooks/__tests__/useDeckMapUtils.test.ts

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,7 @@ describe('getRunCurrentModulesInfo', () => {
198198
const result = getRunCurrentModulesInfo({
199199
runRecord: null as any,
200200
deckDef: mockDeckDef,
201-
labwareDefinitionsByUri: {},
202-
})
203-
204-
expect(result).toEqual([])
205-
})
206-
207-
it('should return an empty array if protocolAnalysis is null', () => {
208-
const result = getRunCurrentModulesInfo({
209-
runRecord: mockRunRecord,
210-
deckDef: mockDeckDef,
211-
labwareDefinitionsByUri: null,
201+
runLwDefsByUri: {},
212202
})
213203

214204
expect(result).toEqual([])
@@ -219,7 +209,7 @@ describe('getRunCurrentModulesInfo', () => {
219209
const result = getRunCurrentModulesInfo({
220210
runRecord: mockRunRecord,
221211
deckDef: mockDeckDef,
222-
labwareDefinitionsByUri: {
212+
runLwDefsByUri: {
223213
'opentrons/opentrons_96_pcr_adapter/1': 'MOCK_LW_DEF',
224214
} as any,
225215
})
@@ -242,7 +232,7 @@ describe('getRunCurrentModulesInfo', () => {
242232
data: { modules: [mockModule], labware: [] },
243233
},
244234
deckDef: mockDeckDef,
245-
labwareDefinitionsByUri: {},
235+
runLwDefsByUri: {},
246236
})
247237
expect(result).toEqual([
248238
{
@@ -261,7 +251,7 @@ describe('getRunCurrentModulesInfo', () => {
261251
const result = getRunCurrentModulesInfo({
262252
runRecord: mockRunRecord,
263253
deckDef: mockDeckDef,
264-
labwareDefinitionsByUri: null,
254+
runLwDefsByUri: {},
265255
})
266256
expect(result).toEqual([])
267257
})
@@ -286,7 +276,7 @@ describe('getRunCurrentLabwareInfo', () => {
286276
it('should return an empty array if runRecord is null', () => {
287277
const result = getRunCurrentLabwareInfo({
288278
runRecord: undefined,
289-
labwareDefinitionsByUri: {} as any,
279+
runLwDefsByUri: {} as any,
290280
})
291281

292282
expect(result).toEqual([])
@@ -295,7 +285,7 @@ describe('getRunCurrentLabwareInfo', () => {
295285
it('should return an empty array if protocolAnalysis is null', () => {
296286
const result = getRunCurrentLabwareInfo({
297287
runRecord: { data: { labware: [] } } as any,
298-
labwareDefinitionsByUri: null,
288+
runLwDefsByUri: {},
299289
})
300290

301291
expect(result).toEqual([])
@@ -309,7 +299,7 @@ describe('getRunCurrentLabwareInfo', () => {
309299

310300
const result = getRunCurrentLabwareInfo({
311301
runRecord: { data: { labware: [mockPickUpTipLwSlotName] } } as any,
312-
labwareDefinitionsByUri: {
302+
runLwDefsByUri: {
313303
[mockPickUpTipLabware.definitionUri]: mockLabwareDef,
314304
},
315305
})

app/src/organisms/ErrorRecoveryFlows/hooks/useDeckMapUtils.ts

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ interface UseDeckMapUtilsProps {
4242
runId: ErrorRecoveryFlowsProps['runId']
4343
protocolAnalysis: ErrorRecoveryFlowsProps['protocolAnalysis']
4444
failedLabwareUtils: UseFailedLabwareUtilsResult
45-
labwareDefinitionsByUri: ERUtilsProps['labwareDefinitionsByUri']
45+
runLwDefsByUri: ERUtilsProps['runLwDefsByUri']
4646
runRecord: Run | undefined
4747
}
4848

@@ -65,7 +65,7 @@ export function useDeckMapUtils({
6565
runRecord,
6666
runId,
6767
failedLabwareUtils,
68-
labwareDefinitionsByUri,
68+
runLwDefsByUri,
6969
}: UseDeckMapUtilsProps): UseDeckMapUtilsResult {
7070
const robotType = protocolAnalysis?.robotType ?? OT2_ROBOT_TYPE
7171
const deckConfig = getSimplestDeckConfigForProtocol(protocolAnalysis)
@@ -78,9 +78,9 @@ export function useDeckMapUtils({
7878
getRunCurrentModulesInfo({
7979
runRecord,
8080
deckDef,
81-
labwareDefinitionsByUri,
81+
runLwDefsByUri,
8282
}),
83-
[runRecord, deckDef, labwareDefinitionsByUri]
83+
[runRecord, deckDef, runLwDefsByUri]
8484
)
8585

8686
const runCurrentModules = useMemo(
@@ -94,8 +94,8 @@ export function useDeckMapUtils({
9494
)
9595

9696
const currentLabwareInfo = useMemo(
97-
() => getRunCurrentLabwareInfo({ runRecord, labwareDefinitionsByUri }),
98-
[runRecord, labwareDefinitionsByUri]
97+
() => getRunCurrentLabwareInfo({ runRecord, runLwDefsByUri }),
98+
[runRecord, runLwDefsByUri]
9999
)
100100

101101
const { updatedModules, remainingLabware } = useMemo(
@@ -114,32 +114,24 @@ export function useDeckMapUtils({
114114
)
115115

116116
const movedLabwareDef =
117-
labwareDefinitionsByUri != null && failedLabwareUtils.failedLabware != null
118-
? labwareDefinitionsByUri[failedLabwareUtils.failedLabware.definitionUri]
117+
runLwDefsByUri != null && failedLabwareUtils.failedLabware != null
118+
? runLwDefsByUri[failedLabwareUtils.failedLabware.definitionUri]
119119
: null
120120

121121
const moduleRenderInfo = useMemo(
122122
() =>
123-
runRecord != null && labwareDefinitionsByUri != null
124-
? getRunModuleRenderInfo(
125-
runRecord.data,
126-
deckDef,
127-
labwareDefinitionsByUri
128-
)
123+
runRecord != null && runLwDefsByUri != null
124+
? getRunModuleRenderInfo(runRecord.data, deckDef, runLwDefsByUri)
129125
: [],
130-
[deckDef, labwareDefinitionsByUri, runRecord]
126+
[deckDef, runLwDefsByUri, runRecord]
131127
)
132128

133129
const labwareRenderInfo = useMemo(
134130
() =>
135-
runRecord != null && labwareDefinitionsByUri != null
136-
? getRunLabwareRenderInfo(
137-
runRecord.data,
138-
labwareDefinitionsByUri,
139-
deckDef
140-
)
131+
runRecord != null && runLwDefsByUri != null
132+
? getRunLabwareRenderInfo(runRecord.data, runLwDefsByUri, deckDef)
141133
: [],
142-
[deckDef, labwareDefinitionsByUri, runRecord]
134+
[deckDef, runLwDefsByUri, runRecord]
143135
)
144136

145137
return {
@@ -258,13 +250,13 @@ interface RunCurrentModuleInfo {
258250
export const getRunCurrentModulesInfo = ({
259251
runRecord,
260252
deckDef,
261-
labwareDefinitionsByUri,
253+
runLwDefsByUri,
262254
}: {
263255
runRecord: UseDeckMapUtilsProps['runRecord']
264256
deckDef: DeckDefinition
265-
labwareDefinitionsByUri?: LabwareDefinitionsByUri | null
257+
runLwDefsByUri: UseDeckMapUtilsProps['runLwDefsByUri']
266258
}): RunCurrentModuleInfo[] => {
267-
if (runRecord == null || labwareDefinitionsByUri == null) {
259+
if (runRecord == null) {
268260
return []
269261
} else {
270262
return runRecord.data.modules.reduce<RunCurrentModuleInfo[]>(
@@ -281,7 +273,7 @@ export const getRunCurrentModulesInfo = ({
281273

282274
const nestedLabwareDef =
283275
nestedLabware != null
284-
? labwareDefinitionsByUri[nestedLabware.definitionUri]
276+
? runLwDefsByUri[nestedLabware.definitionUri]
285277
: null
286278

287279
const slotPosition = getPositionFromSlotId(
@@ -325,12 +317,12 @@ interface RunCurrentLabwareInfo {
325317
// Derive the labware info necessary to render labware on the deck.
326318
export function getRunCurrentLabwareInfo({
327319
runRecord,
328-
labwareDefinitionsByUri,
320+
runLwDefsByUri,
329321
}: {
330322
runRecord: UseDeckMapUtilsProps['runRecord']
331-
labwareDefinitionsByUri?: LabwareDefinitionsByUri | null
323+
runLwDefsByUri: UseDeckMapUtilsProps['runLwDefsByUri']
332324
}): RunCurrentLabwareInfo[] {
333-
if (runRecord == null || labwareDefinitionsByUri == null) {
325+
if (runRecord == null) {
334326
return []
335327
} else {
336328
const allLabware = runRecord.data.labware.reduce(
@@ -341,7 +333,7 @@ export function getRunCurrentLabwareInfo({
341333
runRecord,
342334
true
343335
) // Exclude modules since handled separately.
344-
const labwareDef = getLabwareDefinition(lw, labwareDefinitionsByUri)
336+
const labwareDef = getLabwareDefinition(lw, runLwDefsByUri)
345337

346338
if (slotName == null || labwareLocation == null) {
347339
return acc

app/src/organisms/ErrorRecoveryFlows/hooks/useERUtils.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ import { useCleanupRecoveryState } from './useCleanupRecoveryState'
2222
import { useFailedPipetteUtils } from './useFailedPipetteUtils'
2323
import { getRunningStepCountsFrom } from '/app/resources/protocols'
2424

25-
import type {
26-
LabwareDefinition2,
27-
LabwareDefinitionsByUri,
28-
RobotType,
29-
} from '@opentrons/shared-data'
25+
import type { LabwareDefinition2, RobotType } from '@opentrons/shared-data'
3026
import type { IRecoveryMap, RouteStep, RecoveryRoute } from '../types'
3127
import type { ErrorRecoveryFlowsProps } from '..'
3228
import type { UseRouteUpdateActionsResult } from './useRouteUpdateActions'
@@ -54,7 +50,6 @@ export type ERUtilsProps = Omit<ErrorRecoveryFlowsProps, 'failedCommand'> & {
5450
failedCommand: ReturnType<typeof useRetainedFailedCommandBySource>
5551
isActiveUser: UseRecoveryTakeoverResult['isActiveUser']
5652
allRunDefs: LabwareDefinition2[]
57-
labwareDefinitionsByUri: LabwareDefinitionsByUri | null
5853
}
5954

6055
export interface ERUtilsResults {
@@ -90,7 +85,7 @@ export function useERUtils({
9085
isActiveUser,
9186
allRunDefs,
9287
unvalidatedFailedCommand,
93-
labwareDefinitionsByUri,
88+
runLwDefsByUri,
9489
}: ERUtilsProps): ERUtilsResults {
9590
const { data: attachedInstruments } = useInstrumentsQuery()
9691
const { data: runRecord } = useNotifyRunQuery(runId)
@@ -185,7 +180,7 @@ export function useERUtils({
185180
runRecord,
186181
protocolAnalysis,
187182
failedLabwareUtils,
188-
labwareDefinitionsByUri,
183+
runLwDefsByUri,
189184
})
190185

191186
const recoveryActionMutationUtils = useRecoveryActionMutation(

0 commit comments

Comments
 (0)