Skip to content

Commit b133a76

Browse files
authored
DM-8214 handling server errors in charts, merge pr #244
DM-8214 - handling server errors in charts
2 parents d1b3c44 + 1d7545c commit b133a76

File tree

5 files changed

+82
-8
lines changed

5 files changed

+82
-8
lines changed

src/firefly/js/charts/ChartDataType.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {logError} from '../util/WebUtil.js';
1212
* @prop {string} id - unique chart data type id
1313
* @prop {Function} fetchData - function to load chart data element data: fetchData(dispatch, chartId, chartDataElementId)
1414
* @prop {Function} fetchParamsChanged - function to determine if fetch is necessary: fetchParamsChanged(oldOptions, newOptions)
15-
* @prop {Function} getUpdatedOptions - function to resolve the options, which depend on table or chart data getUpdatedOptions(options, tblId, data, meta)
15+
* @prop {Function} [getUpdatedOptions=undefined] - function to resolve the options, which depend on table or chart data getUpdatedOptions(options, tblId, data, meta)
1616
* @prop {boolean} [fetchOnTblSort=true] - if false, don't re-fetch data on tbl sort
1717
*/
1818

src/firefly/js/charts/ChartsCntlr.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ function doChartDataFetch(dispatch, payload, getChartDataType) {
311311
* @param payload.chartId
312312
* @param payload.chartDataElementId
313313
* @param payload.isDataReady
314+
* @param payload.error
315+
* @param payload.error.message
316+
* @param payload.error.reason
314317
* @param payload.data
315318
* @param [payload.options]
316319
* @param [payload.meta]
@@ -522,6 +525,25 @@ export function getChartDataElement(chartId, chartDataElementId=FIRST_CDEL_ID) {
522525
return get(flux.getState(), [CHART_SPACE_PATH, 'data', chartId, 'chartDataElements', chartDataElementId]);
523526
}
524527

528+
/**
529+
* Get error object associated with the given chart data element
530+
* @param chartId
531+
* @returns {Array<{message:string, reason:object}>} an array of error objects
532+
*/
533+
export function getErrors(chartId) {
534+
const chartDataElements = get(flux.getState(), [CHART_SPACE_PATH, 'data', chartId, 'chartDataElements']);
535+
const errors = [];
536+
if (chartDataElements) {
537+
Object.keys(chartDataElements).forEach((id) => {
538+
const error = chartDataElements[id].error;
539+
if (error) {
540+
errors.push(error);
541+
}
542+
});
543+
}
544+
return errors;
545+
}
546+
525547
export function getExpandedChartProps() {
526548
const chartId = get(flux.getState(), [CHART_SPACE_PATH, 'ui', 'expanded']);
527549
return {chartId};

src/firefly/js/charts/dataTypes/HistogramCDT.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,24 @@ function fetchColData(dispatch, chartId, chartDataElementId) {
161161
chartId,
162162
chartDataElementId,
163163
isDataReady: true,
164+
error: undefined,
164165
options : histogramParams,
165166
data: histogramData,
166167
meta: {tblSource}
167168
}));
168169
}
169170
).catch(
170171
(reason) => {
171-
console.error(`Failed to fetch histogram data: ${reason}`);
172+
const message = 'Failed to fetch histogram data';
173+
logError(`${message}: ${reason}`);
174+
dispatch(chartDataUpdate(
175+
{
176+
chartId,
177+
chartDataElementId,
178+
isDataReady: true,
179+
error: {message, reason},
180+
data: undefined
181+
}));
172182
}
173183
);
174184
}

src/firefly/js/charts/dataTypes/XYColsCDT.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {updateSet, logError} from '../../util/WebUtil.js';
88
import {get, omitBy, isEmpty, isString, isUndefined} from 'lodash';
99

1010
import {MetaConst} from '../../data/MetaConst.js';
11-
import {doFetchTable, getColumn, getTblById, isFullyLoaded, cloneRequest} from '../../tables/TableUtil.js';
11+
import {fetchTable} from '../../rpc/SearchServicesJson.js';
12+
import {getColumn, getTblById, isFullyLoaded, cloneRequest} from '../../tables/TableUtil.js';
1213

1314
import {getChartDataElement, dispatchChartAdd, dispatchChartOptionsUpdate, chartDataUpdate} from './../ChartsCntlr.js';
1415
import {colWithName, getNumericCols, SCATTER} from './../ChartUtil.js';
@@ -325,7 +326,7 @@ function fetchPlotData(dispatch, chartId, chartDataElementId) {
325326
});
326327
req.tbl_id = `xy-${chartId}`;
327328

328-
doFetchTable(req).then(
329+
fetchTable(req).then(
329330
(tableModel) => {
330331

331332
// make sure we only save the data from the latest fetch
@@ -369,14 +370,24 @@ function fetchPlotData(dispatch, chartId, chartDataElementId) {
369370
chartId,
370371
chartDataElementId,
371372
isDataReady: true,
373+
error: undefined,
372374
options: getUpdatedParams(xyPlotParams, tblId, xyPlotData),
373375
data: xyPlotData,
374376
meta: {tblSource, decimatedUnzoomed}
375377
}));
376378
}
377379
).catch(
378380
(reason) => {
379-
logError(`Failed to fetch XY plot data: ${reason}`);
381+
const message = 'Failed to fetch XY plot data';
382+
logError(`${message}: ${reason}`);
383+
dispatch(chartDataUpdate(
384+
{
385+
chartId,
386+
chartDataElementId,
387+
isDataReady: true,
388+
error: {message, reason},
389+
data: undefined
390+
}));
380391
}
381392
);
382393

src/firefly/js/charts/ui/ChartPanel.jsx

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class ChartPanelView extends Component {
9090

9191
var {widthPx, heightPx, componentKey, optionsShown} = this.state;
9292
const knownSize = widthPx && heightPx;
93-
93+
const errors = ChartsCntlr.getErrors(chartId);
9494

9595
if (showChart) {
9696
// chart with toolbar and options
@@ -113,7 +113,10 @@ class ChartPanelView extends Component {
113113
<Resizable id='chart-resizer' onResize={this.onResize}
114114
className='ChartPanel__chartresizer'>
115115
<div style={{overflow:'auto',width:widthPx,height:heightPx}}>
116-
{knownSize ? <Chart {...Object.assign({}, this.props, {widthPx, heightPx})}/> :
116+
{knownSize ?
117+
errors.length > 0 ?
118+
<ErrorPanel errors={errors}/> :
119+
<Chart {...Object.assign({}, this.props, {widthPx, heightPx})}/> :
117120
<div/>}
118121
</div>
119122
</Resizable>
@@ -135,7 +138,11 @@ class ChartPanelView extends Component {
135138
<Resizable id='chart-resizer' onResize={this.onResize}
136139
className='ChartPanel__chartresizer'>
137140
<div style={{overflow:'auto',width:widthPx,height:heightPx}}>
138-
{knownSize ? <Chart {...Object.assign({}, this.props, {widthPx, heightPx})}/> :
141+
{knownSize ?
142+
errors.length > 0 ?
143+
<ErrorPanel errors={errors}/> :
144+
<Chart {...Object.assign({}, this.props, {widthPx, heightPx})}/> :
145+
139146
<div/>}
140147
</div>
141148
</Resizable>
@@ -191,6 +198,30 @@ ChartPanelView.defaultProps = {
191198
showChart: true
192199
};
193200

201+
function ErrorPanel({errors}) {
202+
return (
203+
<div style={{position: 'relative', width: '100%', height: '100%'}}>
204+
{errors.map((error, i) => {
205+
const {message='Error', reason=''} = error;
206+
return (
207+
<div key={i} style={{padding: 20, textAlign: 'center', overflowWrap: 'normal'}}>
208+
<h3>{message}</h3>
209+
{`${reason}`}
210+
</div>
211+
);
212+
})}
213+
</div>
214+
);
215+
}
216+
217+
ErrorPanel.propTypes = {
218+
errors: PropTypes.arrayOf(
219+
PropTypes.shape({
220+
message: PropTypes.string,
221+
reason: PropTypes.oneOfType([PropTypes.object,PropTypes.string]) // reason can be an Error object
222+
}))
223+
};
224+
194225
export class ChartPanel extends Component {
195226

196227
constructor(props) {

0 commit comments

Comments
 (0)