Fix the error handling for tables and graphs on DE. Use one function to get time series.

pull/1232/head
Hunter Trujillo 2017-04-07 18:17:01 -06:00 committed by Andrew Watkins
parent 3d9f36134b
commit 6fe6699ea1
3 changed files with 74 additions and 51 deletions

View File

@ -86,14 +86,19 @@ const ChronoTable = React.createClass({
this.setState({isLoading: true})
// second param is db, we want to leave this blank
try {
const results = await this.props.fetchTimeSeries(query.host, undefined, query)
const {results} = await this.props.fetchTimeSeries({source: query.host, query})
this.setState({isLoading: false})
if (!results) {
return this.setState({cellData: emptyCells})
}
const cellData = _.get(results, ['series', '0'], {})
const cellData = _.get(results, ['0', 'series', '0'], false)
if (!cellData) {
return this.setState({cellData: emptyCells})
}
this.setState({cellData})
} catch (error) {
this.setState({

View File

@ -2,35 +2,46 @@ import {proxy} from 'utils/queryUrlGenerator'
import {editQueryStatus} from 'src/data_explorer/actions/view'
import _ from 'lodash'
export const fetchTimeSeriesAsync = (source, db, query) => async (dispatch) => {
export const handleLoading = (query, dispatch) => {
dispatch(editQueryStatus(query.id, {loading: true}))
}
// {results: [{}]}
export const handleSuccess = (data, query, dispatch) => {
const {results} = data
const error = _.get(results, ['0', 'error'], false)
const series = _.get(results, ['0', 'series'], false)
// 200 from server and no results = warn
if (!series && !error) {
dispatch(editQueryStatus(query.id, {warn: 'Your query is syntactically correct but returned no results'}))
return data
}
// 200 from chrono server but influx returns an "error" = warning
if (error) {
dispatch(editQueryStatus(query.id, {warn: error}))
return data
}
// 200 from server and results contains data = success
dispatch(editQueryStatus(query.id, {success: 'Success!'}))
return data
}
export const handleError = (error, query, dispatch) => {
const message = _.get(error, ['data', 'message'], error)
// 400 from chrono server = fail
dispatch(editQueryStatus(query.id, {error: message}))
console.error(error)
}
export const fetchTimeSeriesAsync = ({source, db, rp, query}) => async (dispatch) => {
handleLoading(query, dispatch)
try {
const {data} = await proxy({source, db, query: query.text})
const results = _.get(data, ['results', '0'], false)
const warn = _.get(results, 'error', false)
// 200 from server and no results = warn
if (_.isEmpty(results)) {
dispatch(editQueryStatus(query.id, {warn: 'Your query is syntactically correct but returned no results'}))
return results
}
// 200 from chrono server but influx returns an error = warning
if (warn) {
dispatch(editQueryStatus(query.id, {warn}))
return warn
}
// 200 from server and results contains data = success
dispatch(editQueryStatus(query.id, {success: 'Success!'}))
return results
const {data} = await proxy({source, db, rp, query: query.text})
return handleSuccess(data, query, dispatch)
} catch (error) {
const message = _.get(error, ['data', 'message'], error)
// 400 from chrono server = fail
dispatch(editQueryStatus(query.id, {error: message}))
console.error(error)
handleError(error, query, dispatch)
throw error
}
}

View File

@ -1,21 +1,21 @@
import React, {PropTypes} from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import _ from 'lodash'
import {proxy} from 'utils/queryUrlGenerator'
function _fetchTimeSeries(source, db, rp, query) {
return proxy({source, db, rp, query})
}
import {fetchTimeSeriesAsync} from 'shared/actions/timeSeries'
const {
element,
number,
arrayOf,
shape,
element,
func,
number,
oneOfType,
shape,
string,
} = PropTypes
export default function AutoRefresh(ComposedComponent) {
const AutoRefresh = (ComposedComponent) => {
const wrapper = React.createClass({
propTypes: {
children: element,
@ -24,6 +24,7 @@ export default function AutoRefresh(ComposedComponent) {
host: oneOfType([string, arrayOf(string)]),
text: string,
}).isRequired).isRequired,
fetchTimeSeries: func.isRequired,
},
getInitialState() {
return {
@ -58,7 +59,7 @@ export default function AutoRefresh(ComposedComponent) {
const rightStrs = right.map((q) => `${q.host}${q.text}`)
return _.difference(_.union(leftStrs, rightStrs), _.intersection(leftStrs, rightStrs))
},
executeQueries(queries) {
async executeQueries(queries) {
if (!queries.length) {
this.setState({
timeSeries: [],
@ -69,20 +70,20 @@ export default function AutoRefresh(ComposedComponent) {
this.setState({isFetching: true})
let count = 0
const newSeries = []
queries.forEach(({host, database, rp, text}) => {
_fetchTimeSeries(host, database, rp, text).then((resp) => {
newSeries.push({response: resp.data})
count += 1
if (count === queries.length) {
const querySuccessful = !this._noResultsForQuery(newSeries)
this.setState({
lastQuerySuccessful: querySuccessful,
isFetching: false,
timeSeries: newSeries,
})
}
})
})
for (const query of queries) {
const {host, database, rp} = query
const response = await this.props.fetchTimeSeries({source: host, db: database, rp, query})
newSeries.push({response})
count += 1
if (count === queries.length) {
const querySuccessful = !this._noResultsForQuery(newSeries)
this.setState({
lastQuerySuccessful: querySuccessful,
isFetching: false,
timeSeries: newSeries,
})
}
}
},
componentWillUnmount() {
clearInterval(this.intervalID)
@ -148,5 +149,11 @@ export default function AutoRefresh(ComposedComponent) {
},
})
return wrapper
const mapDispatchToProps = (dispatch) => ({
fetchTimeSeries: bindActionCreators(fetchTimeSeriesAsync, dispatch),
})
return connect(null, mapDispatchToProps)(wrapper)
}
export default AutoRefresh