Fix the error handling for tables and graphs on DE. Use one function to get time series.
parent
3d9f36134b
commit
6fe6699ea1
|
@ -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({
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue