Skip to content

Commit

Permalink
feat(app): Add Error Recovery support for in-place commands (#16515)
Browse files Browse the repository at this point in the history
Closes EXEC-777

#16510 appears to have fixed most of the inPlace issues we had seen back in 8.0, and it has (hopefully) greatly simplified the additional support the app needs to provide to get inPlace variations of aspirate/dispense working.

This commit just wires up those commands to the appropriate flows.
  • Loading branch information
mjhuff authored Oct 17, 2024
1 parent 8e3662f commit e15cbe2
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 99 deletions.
1 change: 0 additions & 1 deletion app/src/organisms/ErrorRecoveryFlows/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export { useCurrentlyRecoveringFrom } from './useCurrentlyRecoveringFrom'
export { useErrorMessage } from './useErrorMessage'
export { useErrorName } from './useErrorName'
export { useRecoveryCommands } from './useRecoveryCommands'
export { useRouteUpdateActions } from './useRouteUpdateActions'
Expand Down
13 changes: 0 additions & 13 deletions app/src/organisms/ErrorRecoveryFlows/hooks/useErrorMessage.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,93 +6,74 @@ import { getErrorKind } from '../getErrorKind'
import type { RunCommandError, RunTimeCommand } from '@opentrons/shared-data'

describe('getErrorKind', () => {
it(`returns ${ERROR_KINDS.NO_LIQUID_DETECTED} for ${DEFINED_ERROR_TYPES.LIQUID_NOT_FOUND} errorType`, () => {
const result = getErrorKind({
commandType: 'liquidProbe',
error: {
isDefined: true,
errorType: DEFINED_ERROR_TYPES.LIQUID_NOT_FOUND,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.NO_LIQUID_DETECTED)
})

it(`returns ${ERROR_KINDS.OVERPRESSURE_WHILE_ASPIRATING} for ${DEFINED_ERROR_TYPES.OVERPRESSURE} errorType`, () => {
const result = getErrorKind({
it.each([
{
commandType: 'aspirate',
error: {
isDefined: true,
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.OVERPRESSURE_WHILE_ASPIRATING)
})

it(`returns ${ERROR_KINDS.OVERPRESSURE_WHILE_DISPENSING} for ${DEFINED_ERROR_TYPES.OVERPRESSURE} errorType`, () => {
const result = getErrorKind({
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
expectedError: ERROR_KINDS.OVERPRESSURE_WHILE_ASPIRATING,
},
{
commandType: 'aspirateInPlace',
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
expectedError: ERROR_KINDS.OVERPRESSURE_WHILE_ASPIRATING,
},
{
commandType: 'dispense',
error: {
isDefined: true,
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.OVERPRESSURE_WHILE_DISPENSING)
})

it(`returns ${ERROR_KINDS.TIP_NOT_DETECTED} for ${DEFINED_ERROR_TYPES.TIP_PHYSICALLY_MISSING} errorType`, () => {
const result = getErrorKind({
commandType: 'pickUpTip',
error: {
isDefined: true,
errorType: DEFINED_ERROR_TYPES.TIP_PHYSICALLY_MISSING,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.TIP_NOT_DETECTED)
})

it(`returns ${ERROR_KINDS.TIP_DROP_FAILED} for ${DEFINED_ERROR_TYPES.TIP_PHYSICALLY_ATTACHED} errorType`, () => {
const result = getErrorKind({
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
expectedError: ERROR_KINDS.OVERPRESSURE_WHILE_DISPENSING,
},
{
commandType: 'dispenseInPlace',
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
expectedError: ERROR_KINDS.OVERPRESSURE_WHILE_DISPENSING,
},
{
commandType: 'dropTip',
error: {
isDefined: true,
errorType: DEFINED_ERROR_TYPES.TIP_PHYSICALLY_ATTACHED,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.TIP_DROP_FAILED)
})

it(`returns ${ERROR_KINDS.GRIPPER_ERROR} for ${DEFINED_ERROR_TYPES.GRIPPER_MOVEMENT} errorType`, () => {
const result = getErrorKind({
errorType: DEFINED_ERROR_TYPES.TIP_PHYSICALLY_ATTACHED,
expectedError: ERROR_KINDS.TIP_DROP_FAILED,
},
{
commandType: 'dropTipInPlace',
errorType: DEFINED_ERROR_TYPES.TIP_PHYSICALLY_ATTACHED,
expectedError: ERROR_KINDS.TIP_DROP_FAILED,
},
{
commandType: 'liquidProbe',
errorType: DEFINED_ERROR_TYPES.LIQUID_NOT_FOUND,
expectedError: ERROR_KINDS.NO_LIQUID_DETECTED,
},
{
commandType: 'pickUpTip',
errorType: DEFINED_ERROR_TYPES.TIP_PHYSICALLY_MISSING,
expectedError: ERROR_KINDS.TIP_NOT_DETECTED,
},
{
commandType: 'moveLabware',
error: {
isDefined: true,
errorType: DEFINED_ERROR_TYPES.GRIPPER_MOVEMENT,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.GRIPPER_ERROR)
})

it(`returns ${ERROR_KINDS.GENERAL_ERROR} for undefined errors`, () => {
const result = getErrorKind({
errorType: DEFINED_ERROR_TYPES.GRIPPER_MOVEMENT,
expectedError: ERROR_KINDS.GRIPPER_ERROR,
},
{
commandType: 'aspirate',
error: {
isDefined: false,
// It should treat this error as undefined because isDefined===false,
// even though the errorType happens to match a defined error.
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.GENERAL_ERROR)
})

it(`returns ${ERROR_KINDS.GENERAL_ERROR} for defined errors not handled explicitly`, () => {
const result = getErrorKind({
errorType: DEFINED_ERROR_TYPES.OVERPRESSURE,
isDefined: false,
expectedError: ERROR_KINDS.GENERAL_ERROR,
},
{
commandType: 'aspirate',
error: ({
isDefined: true,
errorType: 'someHithertoUnknownDefinedErrorType',
} as unknown) as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(ERROR_KINDS.GENERAL_ERROR)
})
errorType: 'someHithertoUnknownDefinedErrorType',
expectedError: ERROR_KINDS.GENERAL_ERROR,
},
])(
'returns $expectedError for $commandType with errorType $errorType',
({ commandType, errorType, expectedError, isDefined = true }) => {
const result = getErrorKind({
commandType,
error: {
isDefined,
errorType,
} as RunCommandError,
} as RunTimeCommand)
expect(result).toEqual(expectedError)
}
)
})
4 changes: 2 additions & 2 deletions app/src/organisms/ErrorRecoveryFlows/utils/getErrorKind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ export function getErrorKind(failedCommand: RunTimeCommand | null): ErrorKind {
// todo(mm, 2024-07-02): Also handle aspirateInPlace and dispenseInPlace.
// https://opentrons.atlassian.net/browse/EXEC-593
if (
commandType === 'aspirate' &&
(commandType === 'aspirate' || commandType === 'aspirateInPlace') &&
errorType === DEFINED_ERROR_TYPES.OVERPRESSURE
) {
return ERROR_KINDS.OVERPRESSURE_WHILE_ASPIRATING
} else if (
commandType === 'dispense' &&
(commandType === 'dispense' || commandType === 'dispenseInPlace') &&
errorType === DEFINED_ERROR_TYPES.OVERPRESSURE
) {
return ERROR_KINDS.OVERPRESSURE_WHILE_DISPENSING
Expand Down

0 comments on commit e15cbe2

Please sign in to comment.