From 567dd5e670d7eb489d700e487da08a6c5f522d06 Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Wed, 31 Jul 2024 12:52:35 -0400 Subject: [PATCH] feat(api-client, react-api-client): Add client support for `/runs/:runId/errorRecoveryPolicy` (#15851) Works towards EXEC-560 --- api-client/src/runs/index.ts | 2 + api-client/src/runs/types.ts | 26 ++++++++ .../src/runs/updateErrorRecoveryPolicy.ts | 48 ++++++++++++++ react-api-client/src/runs/index.ts | 1 + .../src/runs/useUpdateErrorRecoveryPolicy.ts | 62 +++++++++++++++++++ 5 files changed, 139 insertions(+) create mode 100644 api-client/src/runs/updateErrorRecoveryPolicy.ts create mode 100644 react-api-client/src/runs/useUpdateErrorRecoveryPolicy.ts diff --git a/api-client/src/runs/index.ts b/api-client/src/runs/index.ts index 01653713c81..02bf0c0e036 100644 --- a/api-client/src/runs/index.ts +++ b/api-client/src/runs/index.ts @@ -12,5 +12,7 @@ export { createRunAction } from './createRunAction' export * from './createLabwareOffset' export * from './createLabwareDefinition' export * from './constants' +export * from './updateErrorRecoveryPolicy' + export * from './types' export type { CreateRunData } from './createRun' diff --git a/api-client/src/runs/types.ts b/api-client/src/runs/types.ts index 45e40f2f8b9..1986a34a0b8 100644 --- a/api-client/src/runs/types.ts +++ b/api-client/src/runs/types.ts @@ -146,3 +146,29 @@ export interface CommandData { // Although run errors are semantically different from command errors, // the server currently happens to use the exact same model for both. export type RunError = RunCommandError + +/** + * Error Policy + */ + +export type IfMatchType = 'ignoreAndContinue' | 'failRun' | 'waitForRecovery' + +export interface ErrorRecoveryPolicy { + policyRules: Array<{ + matchCriteria: { + command: { + commandType: RunTimeCommand['commandType'] + error: { + errorType: RunCommandError['errorType'] + } + } + } + ifMatch: IfMatchType + }> +} + +export interface UpdateErrorRecoveryPolicyRequest { + data: ErrorRecoveryPolicy +} + +export type UpdateErrorRecoveryPolicyResponse = Record diff --git a/api-client/src/runs/updateErrorRecoveryPolicy.ts b/api-client/src/runs/updateErrorRecoveryPolicy.ts new file mode 100644 index 00000000000..2efdd974775 --- /dev/null +++ b/api-client/src/runs/updateErrorRecoveryPolicy.ts @@ -0,0 +1,48 @@ +import { PUT, request } from '../request' + +import type { HostConfig } from '../types' +import type { ResponsePromise } from '../request' +import type { + ErrorRecoveryPolicy, + IfMatchType, + UpdateErrorRecoveryPolicyRequest, + UpdateErrorRecoveryPolicyResponse, +} from './types' +import type { RunCommandError, RunTimeCommand } from '@opentrons/shared-data' + +export type RecoveryPolicyRulesParams = Array<{ + commandType: RunTimeCommand['commandType'] + errorType: RunCommandError['errorType'] + ifMatch: IfMatchType +}> + +export function updateErrorRecoveryPolicy( + config: HostConfig, + runId: string, + policyRules: RecoveryPolicyRulesParams +): ResponsePromise { + const policy = buildErrorRecoveryPolicyBody(policyRules) + + return request< + UpdateErrorRecoveryPolicyResponse, + UpdateErrorRecoveryPolicyRequest + >(PUT, `/runs/${runId}/errorRecoveryPolicy`, { data: policy }, config) +} + +function buildErrorRecoveryPolicyBody( + policyRules: RecoveryPolicyRulesParams +): ErrorRecoveryPolicy { + return { + policyRules: policyRules.map(rule => ({ + matchCriteria: { + command: { + commandType: rule.commandType, + error: { + errorType: rule.errorType, + }, + }, + }, + ifMatch: rule.ifMatch, + })), + } +} diff --git a/react-api-client/src/runs/index.ts b/react-api-client/src/runs/index.ts index 207950738e1..72a087d1529 100644 --- a/react-api-client/src/runs/index.ts +++ b/react-api-client/src/runs/index.ts @@ -15,6 +15,7 @@ export { useAllCommandsAsPreSerializedList } from './useAllCommandsAsPreSerializ export { useCommandQuery } from './useCommandQuery' export * from './useCreateLabwareOffsetMutation' export * from './useCreateLabwareDefinitionMutation' +export * from './useUpdateErrorRecoveryPolicy' export type { UsePlayRunMutationResult } from './usePlayRunMutation' export type { UsePauseRunMutationResult } from './usePauseRunMutation' diff --git a/react-api-client/src/runs/useUpdateErrorRecoveryPolicy.ts b/react-api-client/src/runs/useUpdateErrorRecoveryPolicy.ts new file mode 100644 index 00000000000..1fa379b1bc5 --- /dev/null +++ b/react-api-client/src/runs/useUpdateErrorRecoveryPolicy.ts @@ -0,0 +1,62 @@ +import { useMutation } from 'react-query' + +import { updateErrorRecoveryPolicy } from '@opentrons/api-client' + +import { useHost } from '../api' + +import type { + UseMutationOptions, + UseMutationResult, + UseMutateFunction, +} from 'react-query' +import type { AxiosError } from 'axios' +import type { + RecoveryPolicyRulesParams, + UpdateErrorRecoveryPolicyResponse, + HostConfig, +} from '@opentrons/api-client' + +export type UseUpdateErrorRecoveryPolicyResponse = UseMutationResult< + UpdateErrorRecoveryPolicyResponse, + AxiosError, + RecoveryPolicyRulesParams +> & { + updateErrorRecoveryPolicy: UseMutateFunction< + UpdateErrorRecoveryPolicyResponse, + AxiosError, + RecoveryPolicyRulesParams + > +} + +export type UseUpdateErrorRecoveryPolicyOptions = UseMutationOptions< + UpdateErrorRecoveryPolicyResponse, + AxiosError, + RecoveryPolicyRulesParams +> + +export function useUpdateErrorRecoveryPolicy( + runId: string, + options: UseUpdateErrorRecoveryPolicyOptions = {} +): UseUpdateErrorRecoveryPolicyResponse { + const host = useHost() + + const mutation = useMutation< + UpdateErrorRecoveryPolicyResponse, + AxiosError, + RecoveryPolicyRulesParams + >( + [host, 'runs', runId, 'errorRecoveryPolicy'], + (policyRules: RecoveryPolicyRulesParams) => + updateErrorRecoveryPolicy(host as HostConfig, runId, policyRules) + .then(response => response.data) + .catch(e => { + throw e + }), + options + ) + + return { + ...mutation, + updateErrorRecoveryPolicy: mutation.mutate, + } +}