Skip to content

Commit

Permalink
fix(ui): handle json parsing failures and let the user know
Browse files Browse the repository at this point in the history
  • Loading branch information
hoorayimhelping committed Dec 3, 2019
1 parent e21ebeb commit 5801d9c
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
1. [15853](https://github.com/influxdata/influxdb/pull/15853): Prompt users to make a dashboard when dashboards are empty
1. [15884](https://github.com/influxdata/influxdb/pull/15884): Remove name editing from query definition during threshold check creation
1. [15975](https://github.com/influxdata/influxdb/pull/15975): Wait until user stops dragging and releases marker before zooming in after threshold changes
1. [16101](https://github.com/influxdata/influxdb/pull/16101): Gracefully handle invalid user-supplied JSON

### UI Improvements
1. [15809](https://github.com/influxdata/influxdb/pull/15809): Redesign cards and animations on getting started page
Expand Down
23 changes: 19 additions & 4 deletions ui/src/dashboards/components/DashboardImportOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@ import {withRouter, WithRouterProps} from 'react-router'
import _ from 'lodash'
import {connect} from 'react-redux'

// Copy
import {invalidJSON} from 'src/shared/copy/notifications'

// Actions
import {getDashboardsAsync} from 'src/dashboards/actions'
import {createDashboardFromTemplate as createDashboardFromTemplateAction} from 'src/dashboards/actions'
import {
getDashboardsAsync,
createDashboardFromTemplate as createDashboardFromTemplateAction,
} from 'src/dashboards/actions'
import {notify as notifyAction} from 'src/shared/actions/notifications'

// Types
import ImportOverlay from 'src/shared/components/ImportOverlay'

interface DispatchProps {
createDashboardFromTemplate: typeof createDashboardFromTemplateAction
notify: typeof notifyAction
populateDashboards: typeof getDashboardsAsync
}

Expand All @@ -35,8 +42,15 @@ class DashboardImportOverlay extends PureComponent<Props> {
}

private handleImportDashboard = (uploadContent: string) => {
const {createDashboardFromTemplate, populateDashboards} = this.props
const template = JSON.parse(uploadContent)
const {createDashboardFromTemplate, notify, populateDashboards} = this.props

let template
try {
template = JSON.parse(uploadContent)
} catch (error) {
notify(invalidJSON(error.message))
return
}

if (_.isEmpty(template)) {
this.onDismiss()
Expand All @@ -55,6 +69,7 @@ class DashboardImportOverlay extends PureComponent<Props> {

const mdtp: DispatchProps = {
createDashboardFromTemplate: createDashboardFromTemplateAction,
notify: notifyAction,
populateDashboards: getDashboardsAsync,
}

Expand Down
9 changes: 9 additions & 0 deletions ui/src/shared/copy/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,3 +857,12 @@ export const deleteEndpointFailed = (message: string): Notification => ({
...defaultErrorNotification,
message: `Failed to delete endpoint: ${message}`,
})

export const invalidJSON = (message: string): Notification => {
return {
...defaultErrorNotification,
message: message
? `We couldn’t parse the JSON you entered because it failed with message:\n'${message}'`
: 'We couldn’t parse the JSON you entered because it isn’t valid. Please check the formatting and try again.',
}
}
17 changes: 14 additions & 3 deletions ui/src/tasks/components/TaskImportOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import {connect} from 'react-redux'
// Components
import ImportOverlay from 'src/shared/components/ImportOverlay'

// Copy
import {invalidJSON} from 'src/shared/copy/notifications'

// Actions
import {createTaskFromTemplate as createTaskFromTemplateAction} from 'src/tasks/actions/'
import {notify as notifyAction} from 'src/shared/actions/notifications'

interface DispatchProps {
createTaskFromTemplate: typeof createTaskFromTemplateAction
notify: typeof notifyAction
}

type Props = DispatchProps & WithRouterProps
Expand All @@ -32,18 +37,24 @@ class TaskImportOverlay extends PureComponent<Props> {
}

private handleImportTask = (importString: string) => {
const {createTaskFromTemplate} = this.props
const {createTaskFromTemplate, notify} = this.props

const template = JSON.parse(importString)
let template
try {
template = JSON.parse(importString)
} catch (error) {
notify(invalidJSON(error.message))
return
}

createTaskFromTemplate(template)

this.onDismiss()
}
}

const mdtp: DispatchProps = {
createTaskFromTemplate: createTaskFromTemplateAction,
notify: notifyAction,
}

export default connect<{}, DispatchProps, Props>(
Expand Down
15 changes: 12 additions & 3 deletions ui/src/templates/components/TemplateImportOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {connect} from 'react-redux'
// Components
import ImportOverlay from 'src/shared/components/ImportOverlay'

// Copy
import {invalidJSON} from 'src/shared/copy/notifications'

// Actions
import {
createTemplate as createTemplateAction,
Expand Down Expand Up @@ -49,9 +52,15 @@ class TemplateImportOverlay extends PureComponent<Props> {
}

private handleImportTemplate = (importString: string) => {
const {createTemplate, getTemplates} = this.props

const template = JSON.parse(importString)
const {createTemplate, getTemplates, notify} = this.props

let template
try {
template = JSON.parse(importString)
} catch (error) {
notify(invalidJSON(error.message))
return
}
createTemplate(template)

getTemplates()
Expand Down
18 changes: 16 additions & 2 deletions ui/src/variables/components/VariableImportOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@ import {connect} from 'react-redux'
// Components
import ImportOverlay from 'src/shared/components/ImportOverlay'

// Copy
import {invalidJSON} from 'src/shared/copy/notifications'

// Actions
import {
createVariableFromTemplate as createVariableFromTemplateAction,
getVariables as getVariablesAction,
} from 'src/variables/actions'

import {notify as notifyAction} from 'src/shared/actions/notifications'

interface DispatchProps {
createVariableFromTemplate: typeof createVariableFromTemplateAction
getVariables: typeof getVariablesAction
notify: typeof notifyAction
}

type Props = DispatchProps & WithRouterProps
Expand All @@ -36,9 +42,16 @@ class VariableImportOverlay extends PureComponent<Props> {
}

private handleImportVariable = (uploadContent: string) => {
const {createVariableFromTemplate, getVariables} = this.props
const {createVariableFromTemplate, getVariables, notify} = this.props

let template
try {
template = JSON.parse(uploadContent)
} catch (error) {
notify(invalidJSON(error.message))
return
}

const template = JSON.parse(uploadContent)
createVariableFromTemplate(template)
getVariables()

Expand All @@ -49,6 +62,7 @@ class VariableImportOverlay extends PureComponent<Props> {
const mdtp: DispatchProps = {
createVariableFromTemplate: createVariableFromTemplateAction,
getVariables: getVariablesAction,
notify: notifyAction,
}

export default connect<{}, DispatchProps, Props>(
Expand Down

0 comments on commit 5801d9c

Please sign in to comment.