Merge pull request #4615 from influxdata/flux/show-errors
Show errors instead of 'No Results' when error occursremember-threesizer
commit
5eba55af1e
|
@ -51,6 +51,7 @@ export const getAST = async (request: ASTRequest) => {
|
||||||
export interface GetRawTimeSeriesResult {
|
export interface GetRawTimeSeriesResult {
|
||||||
didTruncate: boolean
|
didTruncate: boolean
|
||||||
csv: string
|
csv: string
|
||||||
|
ok: boolean
|
||||||
uuid?: string
|
uuid?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +75,17 @@ export const getRawTimeSeries = async (
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {body, byteLength, uuid: responseUUID} = await manager.fetchFluxData(
|
const {
|
||||||
url,
|
body,
|
||||||
renderedScript,
|
byteLength,
|
||||||
uuid
|
ok,
|
||||||
)
|
uuid: responseUUID,
|
||||||
|
} = await manager.fetchFluxData(url, renderedScript, uuid)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
csv: body,
|
csv: body,
|
||||||
didTruncate: byteLength >= MAX_RESPONSE_BYTES,
|
didTruncate: byteLength >= MAX_RESPONSE_BYTES,
|
||||||
|
ok,
|
||||||
uuid: responseUUID,
|
uuid: responseUUID,
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -112,7 +115,7 @@ export const getTimeSeries = async (
|
||||||
fluxASTLink: string,
|
fluxASTLink: string,
|
||||||
maxSideLength: number
|
maxSideLength: number
|
||||||
): Promise<GetTimeSeriesResult> => {
|
): Promise<GetTimeSeriesResult> => {
|
||||||
const {csv, didTruncate, uuid: responseUUID} = await getRawTimeSeries(
|
const {csv, didTruncate, ok, uuid: responseUUID} = await getRawTimeSeries(
|
||||||
source,
|
source,
|
||||||
script,
|
script,
|
||||||
uuid,
|
uuid,
|
||||||
|
@ -121,6 +124,12 @@ export const getTimeSeries = async (
|
||||||
maxSideLength
|
maxSideLength
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
// error will be string of {error: value}
|
||||||
|
const error = _.get(JSON.parse(csv), 'error', '')
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
|
||||||
const tables = parseResponse(csv)
|
const tables = parseResponse(csv)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -136,7 +145,6 @@ export const getTimeSeries = async (
|
||||||
console.error('Could not parse response body', error)
|
console.error('Could not parse response body', error)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// REVIEW: Why is this being returned as a `FluxTable[]`?
|
|
||||||
csv,
|
csv,
|
||||||
tables: parseResponseError(csv),
|
tables: parseResponseError(csv),
|
||||||
didTruncate: false,
|
didTruncate: false,
|
||||||
|
|
|
@ -15,6 +15,7 @@ import RawFluxDataTable from 'src/shared/components/TimeMachine/RawFluxDataTable
|
||||||
import TableGraphTransform from 'src/shared/components/TableGraphTransform'
|
import TableGraphTransform from 'src/shared/components/TableGraphTransform'
|
||||||
import TableGraphFormat from 'src/shared/components/TableGraphFormat'
|
import TableGraphFormat from 'src/shared/components/TableGraphFormat'
|
||||||
import AutoRefresh from 'src/shared/components/AutoRefresh'
|
import AutoRefresh from 'src/shared/components/AutoRefresh'
|
||||||
|
import InvalidData from 'src/shared/components/InvalidData'
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import {emptyGraphCopy} from 'src/shared/copy/cell'
|
import {emptyGraphCopy} from 'src/shared/copy/cell'
|
||||||
|
@ -166,6 +167,7 @@ class RefreshingGraph extends Component<Props> {
|
||||||
rawFluxData,
|
rawFluxData,
|
||||||
loading,
|
loading,
|
||||||
uuid,
|
uuid,
|
||||||
|
errorMessage,
|
||||||
}) => {
|
}) => {
|
||||||
const hasValues =
|
const hasValues =
|
||||||
timeSeriesFlux.length ||
|
timeSeriesFlux.length ||
|
||||||
|
@ -180,6 +182,9 @@ class RefreshingGraph extends Component<Props> {
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!hasValues) {
|
if (!hasValues) {
|
||||||
|
if (errorMessage) {
|
||||||
|
return <InvalidData message={errorMessage} />
|
||||||
|
}
|
||||||
if (cellNoteVisibility === NoteVisibility.ShowWhenNoData) {
|
if (cellNoteVisibility === NoteVisibility.ShowWhenNoData) {
|
||||||
return <MarkdownCell text={cellNote} />
|
return <MarkdownCell text={cellNote} />
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ interface RenderProps {
|
||||||
rawFluxData: string
|
rawFluxData: string
|
||||||
loading: RemoteDataState
|
loading: RemoteDataState
|
||||||
uuid: string
|
uuid: string
|
||||||
|
errorMessage: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -66,6 +67,7 @@ interface State {
|
||||||
timeSeriesInfluxQL: TimeSeriesServerResponse[]
|
timeSeriesInfluxQL: TimeSeriesServerResponse[]
|
||||||
timeSeriesFlux: FluxTable[]
|
timeSeriesFlux: FluxTable[]
|
||||||
latestUUID: string
|
latestUUID: string
|
||||||
|
errorMessage: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const TEMP_RES = 300 // FIXME
|
const TEMP_RES = 300 // FIXME
|
||||||
|
@ -118,6 +120,7 @@ class TimeSeries extends PureComponent<Props, State> {
|
||||||
timeSeriesFlux: [],
|
timeSeriesFlux: [],
|
||||||
rawFluxData: '',
|
rawFluxData: '',
|
||||||
latestUUID: null,
|
latestUUID: null,
|
||||||
|
errorMessage: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +150,7 @@ class TimeSeries extends PureComponent<Props, State> {
|
||||||
loading,
|
loading,
|
||||||
isFirstFetch,
|
isFirstFetch,
|
||||||
latestUUID,
|
latestUUID,
|
||||||
|
errorMessage,
|
||||||
} = this.state
|
} = this.state
|
||||||
|
|
||||||
if (isFirstFetch && loading === RemoteDataState.Loading) {
|
if (isFirstFetch && loading === RemoteDataState.Loading) {
|
||||||
|
@ -162,6 +166,7 @@ class TimeSeries extends PureComponent<Props, State> {
|
||||||
rawFluxData,
|
rawFluxData,
|
||||||
loading,
|
loading,
|
||||||
uuid: latestUUID,
|
uuid: latestUUID,
|
||||||
|
errorMessage,
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -222,6 +227,8 @@ class TimeSeries extends PureComponent<Props, State> {
|
||||||
isFirstFetch: false,
|
isFirstFetch: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let errorMessage = ''
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.isFluxQuery) {
|
if (this.isFluxQuery) {
|
||||||
const results = await this.executeFluxQuery(latestUUID)
|
const results = await this.executeFluxQuery(latestUUID)
|
||||||
|
@ -235,8 +242,9 @@ class TimeSeries extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
loading = RemoteDataState.Done
|
loading = RemoteDataState.Done
|
||||||
} catch {
|
} catch (err) {
|
||||||
loading = RemoteDataState.Error
|
loading = RemoteDataState.Error
|
||||||
|
errorMessage = err.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -245,6 +253,7 @@ class TimeSeries extends PureComponent<Props, State> {
|
||||||
rawFluxData,
|
rawFluxData,
|
||||||
loading,
|
loading,
|
||||||
latestUUID: responseUUID,
|
latestUUID: responseUUID,
|
||||||
|
errorMessage,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (grabDataForDownload) {
|
if (grabDataForDownload) {
|
||||||
|
|
|
@ -64,6 +64,11 @@ export const parseTables = (responseChunk: string): FluxTable[] => {
|
||||||
const nonAnnotationData = Papa.parse(nonAnnotationLines).data
|
const nonAnnotationData = Papa.parse(nonAnnotationLines).data
|
||||||
const annotationData = Papa.parse(annotationLines).data
|
const annotationData = Papa.parse(annotationLines).data
|
||||||
const headerRow: string[] = nonAnnotationData[0]
|
const headerRow: string[] = nonAnnotationData[0]
|
||||||
|
|
||||||
|
if (headerRow[1] === 'error' && headerRow[2] === 'reference') {
|
||||||
|
throw new Error(_.get(nonAnnotationData, '1.1'))
|
||||||
|
}
|
||||||
|
|
||||||
const tableColIndex = headerRow.findIndex(h => h === 'table')
|
const tableColIndex = headerRow.findIndex(h => h === 'table')
|
||||||
const timeColIndex = headerRow.findIndex(h => h === '_time')
|
const timeColIndex = headerRow.findIndex(h => h === '_time')
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {LastValues} from 'src/worker/jobs/fluxTablesToSingleStat'
|
||||||
interface DecodeFluxRespWithLimitResult {
|
interface DecodeFluxRespWithLimitResult {
|
||||||
body: string
|
body: string
|
||||||
byteLength: number
|
byteLength: number
|
||||||
|
ok: boolean
|
||||||
uuid?: string
|
uuid?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {MAX_RESPONSE_BYTES} from 'src/flux/constants'
|
||||||
interface DecodeFluxRespWithLimitResult {
|
interface DecodeFluxRespWithLimitResult {
|
||||||
body: string
|
body: string
|
||||||
byteLength: number
|
byteLength: number
|
||||||
|
ok: boolean
|
||||||
uuid?: string
|
uuid?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ export default async (msg: Message): Promise<DecodeFluxRespWithLimitResult> => {
|
||||||
|
|
||||||
reader.cancel()
|
reader.cancel()
|
||||||
|
|
||||||
return {body: bodyString, byteLength: bytesRead, uuid}
|
return {body: bodyString, byteLength: bytesRead, ok: response.ok, uuid}
|
||||||
} else {
|
} else {
|
||||||
bodyString += currentText
|
bodyString += currentText
|
||||||
}
|
}
|
||||||
|
@ -52,5 +53,5 @@ export default async (msg: Message): Promise<DecodeFluxRespWithLimitResult> => {
|
||||||
|
|
||||||
reader.cancel()
|
reader.cancel()
|
||||||
|
|
||||||
return {body: bodyString, byteLength: bytesRead, uuid}
|
return {body: bodyString, byteLength: bytesRead, ok: response.ok, uuid}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,3 +184,11 @@ export const TRUNCATED_RESPONSE = `
|
||||||
#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,long,string,string,string,string,string,string,string
|
#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,long,string,string,string,string,string,string,string
|
||||||
#group,false,false,false,false,false,false,true,true,true,true,true,true,true
|
#group,false,false,false,false,false,false,true,true,true,true,true,true,true
|
||||||
#default,_result,,,,,,,,,,,,`
|
#default,_result,,,,,,,,,,,,`
|
||||||
|
|
||||||
|
export const ERROR =
|
||||||
|
'failed to create physical plan: invalid time bounds from procedure from: bounds contain zero time'
|
||||||
|
export const ERROR_RESPONSE = `#datatype,string,string
|
||||||
|
#group,true,true
|
||||||
|
#default,,
|
||||||
|
,error,reference
|
||||||
|
,${ERROR}`
|
||||||
|
|
|
@ -5,6 +5,8 @@ import {
|
||||||
MULTI_SCHEMA_RESPONSE,
|
MULTI_SCHEMA_RESPONSE,
|
||||||
EXPECTED_COLUMNS,
|
EXPECTED_COLUMNS,
|
||||||
TRUNCATED_RESPONSE,
|
TRUNCATED_RESPONSE,
|
||||||
|
ERROR_RESPONSE,
|
||||||
|
ERROR,
|
||||||
} from 'test/shared/parsing/flux/constants'
|
} from 'test/shared/parsing/flux/constants'
|
||||||
|
|
||||||
describe('Flux results parser', () => {
|
describe('Flux results parser', () => {
|
||||||
|
@ -46,4 +48,10 @@ describe('Flux results parser', () => {
|
||||||
expect(actual).toHaveLength(2)
|
expect(actual).toHaveLength(2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('error responses', () => {
|
||||||
|
it('should throw an error if an error csv ', () => {
|
||||||
|
expect(() => parseResponse(ERROR_RESPONSE)).toThrowError(ERROR)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue