From 46ad19500a8a17573f2e3a0e7ed722091ce764f1 Mon Sep 17 00:00:00 2001 From: Deniz Kusefoglu Date: Tue, 12 May 2020 10:03:22 -0700 Subject: [PATCH] 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 directly --- ui/src/cloud/actions/demodata.ts | 24 +++--------------------- ui/src/cloud/utils/demoDataErrors.ts | 19 +++++++++++++++++++ ui/src/shared/apis/query.ts | 4 +++- ui/src/shared/copy/notifications.ts | 6 ++++++ ui/src/templates/api/index.ts | 4 +++- ui/src/timeMachine/actions/queries.ts | 11 ++++++++++- 6 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 ui/src/cloud/utils/demoDataErrors.ts diff --git a/ui/src/cloud/actions/demodata.ts b/ui/src/cloud/actions/demodata.ts index 6a71cd14fa..ef46f7ae6b 100644 --- a/ui/src/cloud/actions/demodata.ts +++ b/ui/src/cloud/actions/demodata.ts @@ -14,10 +14,9 @@ import {notify} from 'src/shared/actions/notifications' // Selectors import {getOrg} from 'src/organizations/selectors' -import {getAll} from 'src/resources/selectors' // Constants -import {DemoDataTemplates, DemoDataDashboards} from 'src/cloud/constants' +import {DemoDataTemplates} from 'src/cloud/constants' import { demoDataAddBucketFailed, demoDataDeleteBucketFailed, @@ -25,14 +24,7 @@ import { } from 'src/shared/copy/notifications' // Types -import { - Bucket, - RemoteDataState, - GetState, - DemoBucket, - ResourceType, - Dashboard, -} from 'src/types' +import {Bucket, RemoteDataState, GetState, DemoBucket} from 'src/types' import {reportError} from 'src/shared/utils/errors' import {getErrorMessage} from 'src/utils/api' @@ -117,17 +109,7 @@ export const getDemoDataBucketMembership = ({ throw new Error(`dashboard template was not found`) } - await createDashboardFromTemplate(template, orgID) - - const allDashboards = getAll(getState(), ResourceType.Dashboards) - - const createdDashboard = allDashboards.find( - d => d.name === DemoDataDashboards[bucketName] - ) - - if (!createdDashboard) { - throw new Error(`dashboard was not found`) - } + const createdDashboard = await createDashboardFromTemplate(template, orgID) const url = `/orgs/${orgID}/dashboards/${createdDashboard.id}` diff --git a/ui/src/cloud/utils/demoDataErrors.ts b/ui/src/cloud/utils/demoDataErrors.ts new file mode 100644 index 0000000000..f6d0057cd7 --- /dev/null +++ b/ui/src/cloud/utils/demoDataErrors.ts @@ -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 +} diff --git a/ui/src/shared/apis/query.ts b/ui/src/shared/apis/query.ts index 26cfdf8b0c..a55eda9480 100644 --- a/ui/src/shared/apis/query.ts +++ b/ui/src/shared/apis/query.ts @@ -30,6 +30,7 @@ export interface RunQueryLimitResult { export interface RunQueryErrorResult { type: 'UNKNOWN_ERROR' message: string + code?: string } export const runQuery = ( @@ -138,8 +139,9 @@ const processErrorResponse = async ( const body = await response.text() const json = JSON.parse(body) const message = json.message || json.error + const code = json.code - return {type: 'UNKNOWN_ERROR', message} + return {type: 'UNKNOWN_ERROR', message, code} } catch { return {type: 'UNKNOWN_ERROR', message: 'Failed to execute Flux query'} } diff --git a/ui/src/shared/copy/notifications.ts b/ui/src/shared/copy/notifications.ts index 1ef4b91e89..60158b6928 100644 --- a/ui/src/shared/copy/notifications.ts +++ b/ui/src/shared/copy/notifications.ts @@ -476,6 +476,12 @@ export const demoDataSucceeded = ( link, }) +export const demoDataSwitchedOff = (): Notification => ({ + ...defaultErrorNotification, + message: `Demo data buckets are temporarily unavailable. Please try again later.`, + duration: TEN_SECONDS, +}) + // Limits export const readWriteCardinalityLimitReached = ( message: string diff --git a/ui/src/templates/api/index.ts b/ui/src/templates/api/index.ts index c6fff35b64..f9b0f17a77 100644 --- a/ui/src/templates/api/index.ts +++ b/ui/src/templates/api/index.ts @@ -60,7 +60,7 @@ import { export const createDashboardFromTemplate = async ( template: DashboardTemplate, orgID: string -): Promise => { +): Promise => { try { const {content} = template @@ -103,6 +103,8 @@ export const createDashboardFromTemplate = async ( if (getResp.status !== 200) { throw new Error(getResp.data.message) } + + return getResp.data as Dashboard } catch (error) { console.error(error) throw new Error(error.message) diff --git a/ui/src/timeMachine/actions/queries.ts b/ui/src/timeMachine/actions/queries.ts index bed748ed22..593ff0ef96 100644 --- a/ui/src/timeMachine/actions/queries.ts +++ b/ui/src/timeMachine/actions/queries.ts @@ -15,7 +15,11 @@ import {notify} from 'src/shared/actions/notifications' import {hydrateVariables} from 'src/variables/actions/thunks' // Constants -import {rateLimitReached, resultTooLarge} from 'src/shared/copy/notifications' +import { + rateLimitReached, + resultTooLarge, + demoDataSwitchedOff, +} from 'src/shared/copy/notifications' // Utils 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 {buildVarsOption} from 'src/variables/utils/buildVarsOption' import {findNodes} from 'src/shared/utils/ast' +import {isDemoDataAvailabilityError} from 'src/cloud/utils/demoDataErrors' // Types import {CancelBox} from 'src/types/promises' @@ -150,6 +155,10 @@ export const executeQueries = () => async (dispatch, getState: GetState) => { for (const result of results) { if (result.type === 'UNKNOWN_ERROR') { + if (isDemoDataAvailabilityError(result.code, result.message)) { + dispatch(notify(demoDataSwitchedOff())) + } + throw new Error(result.message) }