diff --git a/api/src/opentrons/api/session.py b/api/src/opentrons/api/session.py index bc3c6ea9f49..d5f2dcb9f8c 100755 --- a/api/src/opentrons/api/session.py +++ b/api/src/opentrons/api/session.py @@ -456,6 +456,7 @@ def _snapshot(self): payload = { 'state': self.state, 'startTime': self.startTime, + 'errors': self.errors, 'lastCommand': last_command } return { diff --git a/app/src/components/RunLog/SessionAlert.js b/app/src/components/RunLog/SessionAlert.js index b849dd76d1c..3be24ec3fd3 100644 --- a/app/src/components/RunLog/SessionAlert.js +++ b/app/src/components/RunLog/SessionAlert.js @@ -1,6 +1,8 @@ // @flow import * as React from 'react' +import { useSelector } from 'react-redux' import { AlertItem } from '@opentrons/components' +import { getSessionError } from '../../robot/selectors' import type { SessionStatus } from '../../robot' type Props = { @@ -11,6 +13,7 @@ type Props = { export default function SessionAlert(props: Props) { const { sessionStatus, className, onResetClick } = props + const sessionError = useSelector(getSessionError) switch (sessionStatus) { case 'finished': @@ -63,7 +66,9 @@ export default function SessionAlert(props: Props) { resolving this issue.

} - /> + > + {sessionError !== null &&

{sessionError}

} + ) default: diff --git a/app/src/robot/api-client/client.js b/app/src/robot/api-client/client.js index a390347249a..fb1219c230d 100755 --- a/app/src/robot/api-client/client.js +++ b/app/src/robot/api-client/client.js @@ -409,6 +409,15 @@ export default function client(dispatch) { clearRunTimerInterval() } + // both light and full updates may have the errors list + if (apiSession.errors) { + update.errors = apiSession.errors.map(e => ({ + timestamp: e.timestamp, + message: e.error.message, + line: e.error.line, + })) + } + // if lastCommand key is present, we're dealing with a light update if ('lastCommand' in apiSession) { const lastCommand = apiSession.lastCommand && { diff --git a/app/src/robot/reducer/session.js b/app/src/robot/reducer/session.js index 10e17593603..c4fafa67dd7 100644 --- a/app/src/robot/reducer/session.js +++ b/app/src/robot/reducer/session.js @@ -24,7 +24,11 @@ type Request = { export type SessionState = { sessionRequest: Request, state: SessionStatus, - errors: Array<{}>, + errors: Array<{| + timestamp: number, + line: number, + message: string, + |}>, // TODO(mc, 2018-01-11): command IDs should be strings protocolCommands: Array, protocolCommandsById: { diff --git a/app/src/robot/selectors.js b/app/src/robot/selectors.js index cc8d2ca20ba..ae4d16a3c9c 100644 --- a/app/src/robot/selectors.js +++ b/app/src/robot/selectors.js @@ -172,6 +172,16 @@ export const getRunProgress = createSelector( } ) +export const getSessionError: State => string | null = createSelector( + (state: State) => session(state).runRequest.error, + (state: State) => session(state).errors, + (runError, sessionErrors) => { + if (runError) return runError.message + if (sessionErrors.length > 0) return sessionErrors[0].message + return null + } +) + export function getStartTime(state: State): number | null { const { startTime, remoteTimeCompensation } = session(state)