feat(demodata): Place dd dashboard errors behind feature flag (#18027)
* feat(demodata): Alert user if demodata switched off * feat(demodata): Get created Dashboard directly from api call function * feat(demodata): Return flux errors as part of query response parsing * feat(demodata): Fix linting errors * feat(demodata): Return flux code directlypull/18056/head
parent
f9fd9d4717
commit
46ad19500a
|
@ -14,10 +14,9 @@ import {notify} from 'src/shared/actions/notifications'
|
||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
import {getOrg} from 'src/organizations/selectors'
|
import {getOrg} from 'src/organizations/selectors'
|
||||||
import {getAll} from 'src/resources/selectors'
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import {DemoDataTemplates, DemoDataDashboards} from 'src/cloud/constants'
|
import {DemoDataTemplates} from 'src/cloud/constants'
|
||||||
import {
|
import {
|
||||||
demoDataAddBucketFailed,
|
demoDataAddBucketFailed,
|
||||||
demoDataDeleteBucketFailed,
|
demoDataDeleteBucketFailed,
|
||||||
|
@ -25,14 +24,7 @@ import {
|
||||||
} from 'src/shared/copy/notifications'
|
} from 'src/shared/copy/notifications'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {Bucket, RemoteDataState, GetState, DemoBucket} from 'src/types'
|
||||||
Bucket,
|
|
||||||
RemoteDataState,
|
|
||||||
GetState,
|
|
||||||
DemoBucket,
|
|
||||||
ResourceType,
|
|
||||||
Dashboard,
|
|
||||||
} from 'src/types'
|
|
||||||
import {reportError} from 'src/shared/utils/errors'
|
import {reportError} from 'src/shared/utils/errors'
|
||||||
import {getErrorMessage} from 'src/utils/api'
|
import {getErrorMessage} from 'src/utils/api'
|
||||||
|
|
||||||
|
@ -117,17 +109,7 @@ export const getDemoDataBucketMembership = ({
|
||||||
throw new Error(`dashboard template was not found`)
|
throw new Error(`dashboard template was not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
await createDashboardFromTemplate(template, orgID)
|
const createdDashboard = await createDashboardFromTemplate(template, orgID)
|
||||||
|
|
||||||
const allDashboards = getAll<Dashboard>(getState(), ResourceType.Dashboards)
|
|
||||||
|
|
||||||
const createdDashboard = allDashboards.find(
|
|
||||||
d => d.name === DemoDataDashboards[bucketName]
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!createdDashboard) {
|
|
||||||
throw new Error(`dashboard was not found`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = `/orgs/${orgID}/dashboards/${createdDashboard.id}`
|
const url = `/orgs/${orgID}/dashboards/${createdDashboard.id}`
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {WebsiteMonitoringBucket} from 'src/cloud/constants'
|
||||||
|
import {CLOUD} from 'src/shared/constants'
|
||||||
|
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
|
||||||
|
|
||||||
|
export const isDemoDataAvailabilityError = (
|
||||||
|
errorCode: string,
|
||||||
|
errorMessage: string
|
||||||
|
): boolean => {
|
||||||
|
if (!CLOUD || isFlagEnabled('demodata')) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorCode === 'not found') {
|
||||||
|
if (errorMessage.includes(WebsiteMonitoringBucket)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ export interface RunQueryLimitResult {
|
||||||
export interface RunQueryErrorResult {
|
export interface RunQueryErrorResult {
|
||||||
type: 'UNKNOWN_ERROR'
|
type: 'UNKNOWN_ERROR'
|
||||||
message: string
|
message: string
|
||||||
|
code?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const runQuery = (
|
export const runQuery = (
|
||||||
|
@ -138,8 +139,9 @@ const processErrorResponse = async (
|
||||||
const body = await response.text()
|
const body = await response.text()
|
||||||
const json = JSON.parse(body)
|
const json = JSON.parse(body)
|
||||||
const message = json.message || json.error
|
const message = json.message || json.error
|
||||||
|
const code = json.code
|
||||||
|
|
||||||
return {type: 'UNKNOWN_ERROR', message}
|
return {type: 'UNKNOWN_ERROR', message, code}
|
||||||
} catch {
|
} catch {
|
||||||
return {type: 'UNKNOWN_ERROR', message: 'Failed to execute Flux query'}
|
return {type: 'UNKNOWN_ERROR', message: 'Failed to execute Flux query'}
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,6 +476,12 @@ export const demoDataSucceeded = (
|
||||||
link,
|
link,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const demoDataSwitchedOff = (): Notification => ({
|
||||||
|
...defaultErrorNotification,
|
||||||
|
message: `Demo data buckets are temporarily unavailable. Please try again later.`,
|
||||||
|
duration: TEN_SECONDS,
|
||||||
|
})
|
||||||
|
|
||||||
// Limits
|
// Limits
|
||||||
export const readWriteCardinalityLimitReached = (
|
export const readWriteCardinalityLimitReached = (
|
||||||
message: string
|
message: string
|
||||||
|
|
|
@ -60,7 +60,7 @@ import {
|
||||||
export const createDashboardFromTemplate = async (
|
export const createDashboardFromTemplate = async (
|
||||||
template: DashboardTemplate,
|
template: DashboardTemplate,
|
||||||
orgID: string
|
orgID: string
|
||||||
): Promise<void> => {
|
): Promise<Dashboard> => {
|
||||||
try {
|
try {
|
||||||
const {content} = template
|
const {content} = template
|
||||||
|
|
||||||
|
@ -103,6 +103,8 @@ export const createDashboardFromTemplate = async (
|
||||||
if (getResp.status !== 200) {
|
if (getResp.status !== 200) {
|
||||||
throw new Error(getResp.data.message)
|
throw new Error(getResp.data.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getResp.data as Dashboard
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
throw new Error(error.message)
|
throw new Error(error.message)
|
||||||
|
|
|
@ -15,7 +15,11 @@ import {notify} from 'src/shared/actions/notifications'
|
||||||
import {hydrateVariables} from 'src/variables/actions/thunks'
|
import {hydrateVariables} from 'src/variables/actions/thunks'
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import {rateLimitReached, resultTooLarge} from 'src/shared/copy/notifications'
|
import {
|
||||||
|
rateLimitReached,
|
||||||
|
resultTooLarge,
|
||||||
|
demoDataSwitchedOff,
|
||||||
|
} from 'src/shared/copy/notifications'
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import {getActiveTimeMachine, getActiveQuery} from 'src/timeMachine/selectors'
|
import {getActiveTimeMachine, getActiveQuery} from 'src/timeMachine/selectors'
|
||||||
|
@ -23,6 +27,7 @@ import fromFlux from 'src/shared/utils/fromFlux'
|
||||||
import {getAllVariables, asAssignment} from 'src/variables/selectors'
|
import {getAllVariables, asAssignment} from 'src/variables/selectors'
|
||||||
import {buildVarsOption} from 'src/variables/utils/buildVarsOption'
|
import {buildVarsOption} from 'src/variables/utils/buildVarsOption'
|
||||||
import {findNodes} from 'src/shared/utils/ast'
|
import {findNodes} from 'src/shared/utils/ast'
|
||||||
|
import {isDemoDataAvailabilityError} from 'src/cloud/utils/demoDataErrors'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {CancelBox} from 'src/types/promises'
|
import {CancelBox} from 'src/types/promises'
|
||||||
|
@ -150,6 +155,10 @@ export const executeQueries = () => async (dispatch, getState: GetState) => {
|
||||||
|
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
if (result.type === 'UNKNOWN_ERROR') {
|
if (result.type === 'UNKNOWN_ERROR') {
|
||||||
|
if (isDemoDataAvailabilityError(result.code, result.message)) {
|
||||||
|
dispatch(notify(demoDataSwitchedOff()))
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(result.message)
|
throw new Error(result.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue