From f95fb800fe675d26606e1244fa1c01ef804a3a64 Mon Sep 17 00:00:00 2001 From: Tibor Postek Date: Fri, 28 Feb 2020 13:50:45 +0100 Subject: [PATCH] #117 fix error handling --- js/components/header/errorReport.js | 6 +++-- js/components/nglView/nglProvider.js | 10 +++++---- js/components/nglView/nglView.js | 10 +++++---- .../nglView/redux/dispatchActions.js | 22 +++++++++++++------ .../preview/compounds/compoundList.js | 4 +++- .../preview/compounds/compoundView.js | 2 +- .../compounds/redux/dispatchActions.js | 19 +++++++++------- .../preview/molecule/moleculeList.js | 3 --- .../moleculeGroups/molGroupSelector.js | 4 +++- 9 files changed, 49 insertions(+), 31 deletions(-) diff --git a/js/components/header/errorReport.js b/js/components/header/errorReport.js index ffea89d14..70ef8be9c 100644 --- a/js/components/header/errorReport.js +++ b/js/components/header/errorReport.js @@ -2,8 +2,9 @@ * Created by abradley on 08/10/2018. */ -import React, { memo, useState } from 'react'; +import React, { memo, useContext, useState } from 'react'; import { Button, makeStyles } from '@material-ui/core'; +import { HeaderContext } from './headerContext'; const uuidv4 = require('uuid/v4'); const useStyles = makeStyles(theme => ({ @@ -18,9 +19,10 @@ const useStyles = makeStyles(theme => ({ export const ErrorReport = memo(() => { const classes = useStyles(); const [throwError, setThrowError] = useState(); + const { setError } = useContext(HeaderContext); if (throwError) { - throw new Error('Custom user error.' + uuidv4()); + setError(new Error('Custom user error.' + uuidv4())); } return ( diff --git a/js/components/nglView/nglProvider.js b/js/components/nglView/nglProvider.js index d8df7e892..0f18b406c 100644 --- a/js/components/nglView/nglProvider.js +++ b/js/components/nglView/nglProvider.js @@ -1,14 +1,16 @@ -import React, { createContext, memo, useState } from 'react'; +import React, { createContext, memo, useContext, useState } from 'react'; +import { HeaderContext } from '../header/headerContext'; export const NglContext = createContext(); export const NglProvider = memo(props => { //const nglViewList = useRef([]); const [nglViewList, setNglViewList] = useState([]); + const { setError } = useContext(HeaderContext); const registerNglView = (id, stage) => { if (nglViewList.filter(ngl => ngl.id === id).length > 0) { - console.error('Cannot register NGL View with used ID! ', id); + setError(new Error('Cannot register NGL View with used ID! ', id)); } else { let extendedList = nglViewList; extendedList.push({ id, stage }); @@ -18,7 +20,7 @@ export const NglProvider = memo(props => { const unregisterNglView = id => { if (nglViewList.filter(ngl => ngl.id === id).length === 0) { - console.error('Cannot remove NGL View with given ID! ', id); + setError(new Error('Cannot remove NGL View with given ID! ', id)); } else { for (let i = 0; i < nglViewList.length; i++) { if (nglViewList[i].id === id) { @@ -38,7 +40,7 @@ export const NglProvider = memo(props => { case 1: return filteredList[0]; default: - console.error('Cannot found NGL View with given ID!'); + setError(new Error('Cannot found NGL View with given ID!')); break; } }; diff --git a/js/components/nglView/nglView.js b/js/components/nglView/nglView.js index b3129f76c..038c58cf0 100644 --- a/js/components/nglView/nglView.js +++ b/js/components/nglView/nglView.js @@ -14,6 +14,7 @@ import { throttle } from 'lodash'; import { BACKGROUND_COLOR, NGL_PARAMS } from './constants'; import { makeStyles, useTheme } from '@material-ui/core'; import { VIEWS } from '../../constants/constants'; +import { HeaderContext } from '../header/headerContext'; const useStyles = makeStyles(theme => ({ paper: { @@ -31,6 +32,7 @@ const useStyles = makeStyles(theme => ({ const NglView = memo(({ div_id, height, setOrientation, removeAllNglComponents, handleNglViewPick }) => { // connect to NGL Stage object const { registerNglView, unregisterNglView, getNglView } = useContext(NglContext); + const { setError } = useContext(HeaderContext); const [stage, setStage] = useState(); const classes = useStyles(); const theme = useTheme(); @@ -58,14 +60,14 @@ const NglView = memo(({ div_id, height, setOrientation, removeAllNglComponents, (newStage, getNglView) => { window.addEventListener('resize', handleResize); newStage.mouseControls.add('clickPick-left', (stage, pickingProxy) => - handleNglViewPick(stage, pickingProxy, getNglView) + handleNglViewPick(stage, pickingProxy, getNglView, setError) ); newStage.mouseObserver.signals.scrolled.add(handleOrientationChanged); newStage.mouseObserver.signals.dropped.add(handleOrientationChanged); newStage.mouseObserver.signals.dragged.add(handleOrientationChanged); }, - [handleResize, handleOrientationChanged, handleNglViewPick] + [handleResize, handleOrientationChanged, handleNglViewPick, setError] ); const unregisterStageEvents = useCallback( @@ -73,14 +75,14 @@ const NglView = memo(({ div_id, height, setOrientation, removeAllNglComponents, window.addEventListener('resize', handleResize); window.removeEventListener('resize', handleResize); stage.mouseControls.remove('clickPick-left', (stage, pickingProxy) => - handleNglViewPick(stage, pickingProxy, getNglView) + handleNglViewPick(stage, pickingProxy, getNglView, setError) ); stage.mouseObserver.signals.scrolled.remove(handleOrientationChanged); stage.mouseObserver.signals.dropped.remove(handleOrientationChanged); stage.mouseObserver.signals.dragged.remove(handleOrientationChanged); }, - [handleResize, handleOrientationChanged, handleNglViewPick] + [handleResize, handleOrientationChanged, handleNglViewPick, setError] ); useEffect(() => { diff --git a/js/components/nglView/redux/dispatchActions.js b/js/components/nglView/redux/dispatchActions.js index 7cfed0b8e..5d3da9e76 100644 --- a/js/components/nglView/redux/dispatchActions.js +++ b/js/components/nglView/redux/dispatchActions.js @@ -8,7 +8,7 @@ import { setDuckYankData, setMolGroupOn, setPanddaSiteOn } from '../../../reduce import * as listTypes from '../../../constants/listTypes'; import { selectVectorAndResetCompounds } from '../../../reducers/selection/dispatchActions'; -export const toggleMoleculeGroup = (molGroupId, summaryViewStage, majorViewStage) => (dispatch, getState) => { +export const toggleMoleculeGroup = (molGroupId, summaryViewStage, majorViewStage, setError) => (dispatch, getState) => { const state = getState(); const molGroupSelection = state.selectionReducers.mol_group_selection; const objIdx = molGroupSelection.indexOf(molGroupId); @@ -33,7 +33,9 @@ export const toggleMoleculeGroup = (molGroupId, summaryViewStage, majorViewStage loadObject( Object.assign({ display_div: VIEWS.SUMMARY_VIEW }, generateSphere(currentMolGroup, true)), summaryViewStage - ) + ).catch(error => { + setError(error); + }) ); } else { selectionCopy.splice(objIdx, 1); @@ -51,7 +53,9 @@ export const toggleMoleculeGroup = (molGroupId, summaryViewStage, majorViewStage loadObject( Object.assign({ display_div: VIEWS.SUMMARY_VIEW }, generateSphere(currentMolGroup, false)), summaryViewStage - ) + ).catch(error => { + setError(error); + }) ); dispatch( clearAfterDeselectingMoleculeGroup({ @@ -78,7 +82,7 @@ const processInt = pickingProxy => { return { interaction: tot_name, complex_id: mol_int }; }; -export const handleNglViewPick = (stage, pickingProxy, getNglView) => (dispatch, getState) => { +export const handleNglViewPick = (stage, pickingProxy, getNglView, setError) => (dispatch, getState) => { const state = getState(); if (pickingProxy) { // For assigning the ligand interaction @@ -103,16 +107,20 @@ export const handleNglViewPick = (stage, pickingProxy, getNglView) => (dispatch, name: input_dict['interaction'] + SUFFIX.INTERACTION, OBJECT_TYPE: OBJECT_TYPE.ARROW }; - dispatch(loadObject(objToLoad, stage)); + dispatch( + loadObject(objToLoad, stage).catch(error => { + setError(error); + }) + ); } else if (pickingProxy.component && pickingProxy.component.object && pickingProxy.component.object.name) { let name = pickingProxy.component.object.name; // Ok so now perform logic const type = name.split('_')[0]; const pk = parseInt(name.split('_')[1], 10); if (type === OBJECT_TYPE.MOLECULE_GROUP) { - dispatch(toggleMoleculeGroup(pk, stage, getNglView(VIEWS.MAJOR_VIEW).stage)); + dispatch(toggleMoleculeGroup(pk, stage, getNglView(VIEWS.MAJOR_VIEW).stage), setError); } else if (type === OBJECT_TYPE.MOLGROUPS_SELECT) { - dispatch(toggleMoleculeGroup(pk, stage, getNglView(VIEWS.MAJOR_VIEW).stage)); + dispatch(toggleMoleculeGroup(pk, stage, getNglView(VIEWS.MAJOR_VIEW).stage), setError); } else if (type === listTypes.PANDDA_SITE) { dispatch(setPanddaSiteOn(pk)); } diff --git a/js/components/preview/compounds/compoundList.js b/js/components/preview/compounds/compoundList.js index 30a495b6a..33a6fbd40 100644 --- a/js/components/preview/compounds/compoundList.js +++ b/js/components/preview/compounds/compoundList.js @@ -21,6 +21,7 @@ import InfiniteScroll from 'react-infinite-scroller'; import { getCanLoadMoreCompounds, getCompoundClasses, getCompoundListOffset } from './redux/selectors'; import { NglContext } from '../../nglView/nglProvider'; import { VIEWS } from '../../../constants/constants'; +import { HeaderContext } from '../../header/headerContext'; const useStyles = makeStyles(theme => ({ textField: { @@ -47,6 +48,7 @@ export const CompoundList = memo(({ height }) => { const dispatch = useDispatch(); const { getNglView } = useContext(NglContext); const majorViewStage = getNglView(VIEWS.MAJOR_VIEW) && getNglView(VIEWS.MAJOR_VIEW).stage; + const { setError } = useContext(HeaderContext); const to_query = useSelector(state => state.selectionReducers.to_query); const compoundClasses = useSelector(state => getCompoundClasses(state)); @@ -123,7 +125,7 @@ export const CompoundList = memo(({ height }) => {