feat(demodata): Polish demo data error reporting (#18107)
* feat(demodata): Add type do demodata notification * feat(demodata): do not report dashboard would exceed quota errors * feat(demodata): notify user of demodata availability error in dashboards * feat(demodata): Correct error reporting for demodata * feat(demodata): Add error if demodata bucket is missingpull/18109/head
parent
17f4cc14f2
commit
5102d311b0
|
@ -88,11 +88,9 @@ export const getDemoDataBucketMembership = ({
|
|||
|
||||
dispatch(addBucket(normalizedBucket))
|
||||
} catch (error) {
|
||||
const message = `Failed to add demodata bucket ${bucketName}: ${getErrorMessage(
|
||||
error
|
||||
)}`
|
||||
|
||||
dispatch(notify(demoDataAddBucketFailed(message)))
|
||||
dispatch(
|
||||
notify(demoDataAddBucketFailed(bucketName, getErrorMessage(error)))
|
||||
)
|
||||
|
||||
reportError(error, {
|
||||
name: 'addDemoDataBucket failed in getDemoDataBucketMembership',
|
||||
|
@ -116,15 +114,15 @@ export const getDemoDataBucketMembership = ({
|
|||
|
||||
fireEvent('demoData_bucketAdded', {demo_dataset: bucketName})
|
||||
} catch (error) {
|
||||
const message = `Could not create dashboard for demodata bucket ${bucketName}: ${getErrorMessage(
|
||||
error
|
||||
)}`
|
||||
const errorMessage = getErrorMessage(error)
|
||||
|
||||
dispatch(notify(demoDataAddBucketFailed(message)))
|
||||
dispatch(notify(demoDataAddBucketFailed(bucketName, errorMessage)))
|
||||
|
||||
reportError(error, {
|
||||
name: 'addDemoDataDashboard failed in getDemoDataBucketMembership',
|
||||
})
|
||||
if (errorMessage != 'creating dashboard would exceed quota') {
|
||||
reportError(error, {
|
||||
name: 'addDemoDataDashboard failed in getDemoDataBucketMembership',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +132,7 @@ export const deleteDemoDataBucketMembership = (
|
|||
try {
|
||||
await deleteDemoDataBucketMembershipAJAX(bucket.id)
|
||||
|
||||
// an unsuccessful delete membership req can also return 204 to prevent userID sniffing, so need to check that bucket is really unreachable
|
||||
const resp = await getBucket({bucketID: bucket.id})
|
||||
|
||||
if (resp.status === 200) {
|
||||
|
|
|
@ -40,9 +40,13 @@ export const getDemoDataBucketMembership = async (bucketID: string) => {
|
|||
})
|
||||
|
||||
if (response.status === '200') {
|
||||
// a failed or successful membership POST to sampledata should return 204
|
||||
// if sampledata route is not available gateway responds with 200 a correct success code is 204
|
||||
throw new Error('Could not reach demodata endpoint')
|
||||
}
|
||||
|
||||
if (response.status !== '204') {
|
||||
throw new Error(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteDemoDataBucketMembership = async (bucketID: string) => {
|
||||
|
@ -53,9 +57,13 @@ export const deleteDemoDataBucketMembership = async (bucketID: string) => {
|
|||
})
|
||||
|
||||
if (response.status === '200') {
|
||||
// a failed or successful membership DELETE to sampledata should return 204
|
||||
// if sampledata route is not available gateway responds with 200 a correct success code is 204
|
||||
throw new Error('Could not reach demodata endpoint')
|
||||
}
|
||||
|
||||
if (response.status !== '204') {
|
||||
throw new Error(response.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
|
|
|
@ -6,7 +6,7 @@ export const isDemoDataAvailabilityError = (
|
|||
errorCode: string,
|
||||
errorMessage: string
|
||||
): boolean => {
|
||||
if (!CLOUD || isFlagEnabled('demodata')) {
|
||||
if (!CLOUD) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -17,3 +17,18 @@ export const isDemoDataAvailabilityError = (
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const demoDataError = (orgID: string) => {
|
||||
if (isFlagEnabled('demodata')) {
|
||||
return {
|
||||
message:
|
||||
'It looks like this query requires a demo data bucket to be available. You can add demodata buckets on the buckets tab',
|
||||
linkText: 'Go to buckets',
|
||||
link: `/orgs/${orgID}/load-data/buckets`,
|
||||
}
|
||||
}
|
||||
return {
|
||||
message:
|
||||
'Demo data buckets are temporarily unavailable. Please try again later.',
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,17 @@ import {buildVarsOption} from 'src/variables/utils/buildVarsOption'
|
|||
import 'intersection-observer'
|
||||
import {getAll} from 'src/resources/selectors'
|
||||
import {getOrgIDFromBuckets} from 'src/timeMachine/actions/queries'
|
||||
import {
|
||||
isDemoDataAvailabilityError,
|
||||
demoDataError,
|
||||
} from 'src/cloud/utils/demoDataErrors'
|
||||
|
||||
// Constants
|
||||
import {rateLimitReached, resultTooLarge} from 'src/shared/copy/notifications'
|
||||
import {
|
||||
rateLimitReached,
|
||||
resultTooLarge,
|
||||
demoDataAvailability,
|
||||
} from 'src/shared/copy/notifications'
|
||||
import {TIME_RANGE_START, TIME_RANGE_STOP} from 'src/variables/constants'
|
||||
|
||||
// Actions
|
||||
|
@ -233,6 +241,9 @@ class TimeSeries extends Component<Props & WithRouterProps, State> {
|
|||
|
||||
for (const result of results) {
|
||||
if (result.type === 'UNKNOWN_ERROR') {
|
||||
if (isDemoDataAvailabilityError(result.code, result.message)) {
|
||||
notify(demoDataAvailability(demoDataError(this.props.params.orgID)))
|
||||
}
|
||||
errorMessage = result.message
|
||||
throw new Error(result.message)
|
||||
}
|
||||
|
|
|
@ -452,9 +452,12 @@ export const getBucketFailed = (
|
|||
|
||||
// Demodata buckets
|
||||
|
||||
export const demoDataAddBucketFailed = (error: string): Notification => ({
|
||||
export const demoDataAddBucketFailed = (
|
||||
bucketName: string,
|
||||
message: string
|
||||
): Notification => ({
|
||||
...defaultErrorNotification,
|
||||
message: error,
|
||||
message: `Could not create dashboard for demodata bucket ${bucketName}: ${message}`,
|
||||
})
|
||||
|
||||
export const demoDataDeleteBucketFailed = (
|
||||
|
@ -476,10 +479,15 @@ export const demoDataSucceeded = (
|
|||
link,
|
||||
})
|
||||
|
||||
export const demoDataSwitchedOff = (): Notification => ({
|
||||
export const demoDataAvailability = (error: {
|
||||
message: string
|
||||
linkText?: string
|
||||
link?: string
|
||||
}): Notification => ({
|
||||
...defaultErrorNotification,
|
||||
message: `Demo data buckets are temporarily unavailable. Please try again later.`,
|
||||
...error,
|
||||
duration: TEN_SECONDS,
|
||||
type: 'demoDataAvailabilityError',
|
||||
})
|
||||
|
||||
// Limits
|
||||
|
|
|
@ -18,7 +18,7 @@ import {hydrateVariables} from 'src/variables/actions/thunks'
|
|||
import {
|
||||
rateLimitReached,
|
||||
resultTooLarge,
|
||||
demoDataSwitchedOff,
|
||||
demoDataAvailability,
|
||||
} from 'src/shared/copy/notifications'
|
||||
|
||||
// Utils
|
||||
|
@ -27,7 +27,10 @@ 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'
|
||||
import {
|
||||
isDemoDataAvailabilityError,
|
||||
demoDataError,
|
||||
} from 'src/cloud/utils/demoDataErrors'
|
||||
|
||||
// Types
|
||||
import {CancelBox} from 'src/types/promises'
|
||||
|
@ -160,7 +163,9 @@ 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()))
|
||||
dispatch(
|
||||
notify(demoDataAvailability(demoDataError(getOrg(state).id)))
|
||||
)
|
||||
}
|
||||
|
||||
throw new Error(result.message)
|
||||
|
|
Loading…
Reference in New Issue