Refactor publishNotification errors into errors middleware
parent
4385cc8df8
commit
277c877309
|
@ -4,9 +4,9 @@ import {connect} from 'react-redux'
|
||||||
import {bindActionCreators} from 'redux'
|
import {bindActionCreators} from 'redux'
|
||||||
|
|
||||||
import {getSources} from 'shared/apis'
|
import {getSources} from 'shared/apis'
|
||||||
import {loadSources as loadSourcesAction} from 'shared/actions/sources'
|
|
||||||
import {showDatabases} from 'shared/apis/metaQuery'
|
import {showDatabases} from 'shared/apis/metaQuery'
|
||||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
|
||||||
|
import {loadSources as loadSourcesAction} from 'shared/actions/sources'
|
||||||
import {errorThrown as errorThrownAction} from 'shared/actions/errors'
|
import {errorThrown as errorThrownAction} from 'shared/actions/errors'
|
||||||
|
|
||||||
// Acts as a 'router middleware'. The main `App` component is responsible for
|
// Acts as a 'router middleware'. The main `App` component is responsible for
|
||||||
|
@ -25,7 +25,6 @@ const CheckSources = React.createClass({
|
||||||
pathname: PropTypes.string.isRequired,
|
pathname: PropTypes.string.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
sources: PropTypes.array.isRequired,
|
sources: PropTypes.array.isRequired,
|
||||||
notify: PropTypes.func.isRequired,
|
|
||||||
errorThrown: PropTypes.func.isRequired,
|
errorThrown: PropTypes.func.isRequired,
|
||||||
loadSources: PropTypes.func.isRequired,
|
loadSources: PropTypes.func.isRequired,
|
||||||
},
|
},
|
||||||
|
@ -37,21 +36,20 @@ const CheckSources = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
async componentWillMount() {
|
async componentWillMount() {
|
||||||
const {loadSources, notify, errorThrown} = this.props
|
const {loadSources, errorThrown} = this.props
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {data: {sources}} = await getSources()
|
const {data: {sources}} = await getSources()
|
||||||
loadSources(sources)
|
loadSources(sources)
|
||||||
this.setState({isFetching: false})
|
this.setState({isFetching: false})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorThrown(error)
|
errorThrown(error, 'Unable to connect to Chronograf server')
|
||||||
notify('error', 'Unable to connect to Chronograf server')
|
|
||||||
this.setState({isFetching: false})
|
this.setState({isFetching: false})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async componentWillUpdate(nextProps, nextState) {
|
async componentWillUpdate(nextProps, nextState) {
|
||||||
const {router, location, params, notify, errorThrown, sources} = nextProps
|
const {router, location, params, errorThrown, sources} = nextProps
|
||||||
const {isFetching} = nextState
|
const {isFetching} = nextState
|
||||||
const source = sources.find((s) => s.id === params.sourceID)
|
const source = sources.find((s) => s.id === params.sourceID)
|
||||||
const defaultSource = sources.find((s) => s.default === true)
|
const defaultSource = sources.find((s) => s.default === true)
|
||||||
|
@ -74,8 +72,7 @@ const CheckSources = React.createClass({
|
||||||
try {
|
try {
|
||||||
await showDatabases(source.links.proxy)
|
await showDatabases(source.links.proxy)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorThrown(error)
|
errorThrown(error, 'Unable to connect to source')
|
||||||
notify('error', 'Unable to connect to source')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -101,7 +98,6 @@ const mapStateToProps = ({sources}) => ({
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
loadSources: bindActionCreators(loadSourcesAction, dispatch),
|
loadSources: bindActionCreators(loadSourcesAction, dispatch),
|
||||||
notify: bindActionCreators(publishNotificationAction, dispatch),
|
|
||||||
errorThrown: bindActionCreators(errorThrownAction, dispatch),
|
errorThrown: bindActionCreators(errorThrownAction, dispatch),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import {
|
||||||
killQuery as killQueryProxy,
|
killQuery as killQueryProxy,
|
||||||
} from 'shared/apis/metaQuery'
|
} from 'shared/apis/metaQuery'
|
||||||
|
|
||||||
import {publishNotification} from 'shared/actions/notifications'
|
|
||||||
import {publishAutoDismissingNotification} from 'shared/dispatchers'
|
import {publishAutoDismissingNotification} from 'shared/dispatchers'
|
||||||
import {errorThrown} from 'shared/actions/errors'
|
import {errorThrown} from 'shared/actions/errors'
|
||||||
|
|
||||||
|
@ -263,9 +262,8 @@ export const createUserAsync = (url, user) => async (dispatch) => {
|
||||||
dispatch(publishAutoDismissingNotification('success', 'User created successfully'))
|
dispatch(publishAutoDismissingNotification('success', 'User created successfully'))
|
||||||
dispatch(syncUser(user, data))
|
dispatch(syncUser(user, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to create user: ${error.data.message}`))
|
||||||
// undo optimistic update
|
// undo optimistic update
|
||||||
dispatch(publishNotification('error', `Failed to create user: ${error.data.message}`))
|
|
||||||
setTimeout(() => dispatch(deleteUser(user)), REVERT_STATE_DELAY)
|
setTimeout(() => dispatch(deleteUser(user)), REVERT_STATE_DELAY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,9 +274,8 @@ export const createRoleAsync = (url, role) => async (dispatch) => {
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Role created successfully'))
|
dispatch(publishAutoDismissingNotification('success', 'Role created successfully'))
|
||||||
dispatch(syncRole(role, data))
|
dispatch(syncRole(role, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to create role: ${error.data.message}`))
|
||||||
// undo optimistic update
|
// undo optimistic update
|
||||||
dispatch(publishNotification('error', `Failed to create role: ${error.data.message}`))
|
|
||||||
setTimeout(() => dispatch(deleteRole(role)), REVERT_STATE_DELAY)
|
setTimeout(() => dispatch(deleteRole(role)), REVERT_STATE_DELAY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,8 +287,7 @@ export const createDatabaseAsync = (url, database) => async (dispatch) => {
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Database created successfully'))
|
dispatch(publishAutoDismissingNotification('success', 'Database created successfully'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error))
|
||||||
// undo optimistic update
|
// undo optimistic upda, `Failed to create database: ${error.data.message}`te
|
||||||
dispatch(publishNotification('error', `Failed to create database: ${error.data.message}`))
|
|
||||||
setTimeout(() => dispatch(removeDatabase(database)), REVERT_STATE_DELAY)
|
setTimeout(() => dispatch(removeDatabase(database)), REVERT_STATE_DELAY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,8 +299,7 @@ export const createRetentionPolicyAsync = (database, retentionPolicy) => async (
|
||||||
dispatch(syncRetentionPolicy(database, retentionPolicy, data))
|
dispatch(syncRetentionPolicy(database, retentionPolicy, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error))
|
||||||
// undo optimistic update
|
// undo optimistic upda, `Failed to create retention policy: ${error.data.message}`te
|
||||||
dispatch(publishNotification('error', `Failed to create retention policy: ${error.data.message}`))
|
|
||||||
setTimeout(() => dispatch(removeRetentionPolicy(database, retentionPolicy)), REVERT_STATE_DELAY)
|
setTimeout(() => dispatch(removeRetentionPolicy(database, retentionPolicy)), REVERT_STATE_DELAY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,8 +311,7 @@ export const updateRetentionPolicyAsync = (database, retentionPolicy, updates) =
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Retention policy updated successfully'))
|
dispatch(publishAutoDismissingNotification('success', 'Retention policy updated successfully'))
|
||||||
dispatch(syncRetentionPolicy(database, retentionPolicy, data))
|
dispatch(syncRetentionPolicy(database, retentionPolicy, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to update retention policy: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to update retention policy: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,8 +334,7 @@ export const deleteRoleAsync = (role) => async (dispatch) => {
|
||||||
await deleteRoleAJAX(role.links.self)
|
await deleteRoleAJAX(role.links.self)
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Role deleted'))
|
dispatch(publishAutoDismissingNotification('success', 'Role deleted'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to delete role: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to delete role: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +344,7 @@ export const deleteUserAsync = (user) => async (dispatch) => {
|
||||||
await deleteUserAJAX(user.links.self)
|
await deleteUserAJAX(user.links.self)
|
||||||
dispatch(publishAutoDismissingNotification('success', 'User deleted'))
|
dispatch(publishAutoDismissingNotification('success', 'User deleted'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to delete user: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to delete user: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,8 +354,7 @@ export const deleteDatabaseAsync = (database) => async (dispatch) => {
|
||||||
await deleteDatabaseAJAX(database.links.self)
|
await deleteDatabaseAJAX(database.links.self)
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Database deleted'))
|
dispatch(publishAutoDismissingNotification('success', 'Database deleted'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to delete database: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to delete database: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,8 +364,7 @@ export const deleteRetentionPolicyAsync = (database, retentionPolicy) => async (
|
||||||
await deleteRetentionPolicyAJAX(retentionPolicy.links.self)
|
await deleteRetentionPolicyAJAX(retentionPolicy.links.self)
|
||||||
dispatch(publishAutoDismissingNotification('success', `Retention policy ${retentionPolicy.name} deleted`))
|
dispatch(publishAutoDismissingNotification('success', `Retention policy ${retentionPolicy.name} deleted`))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to delete retentionPolicy: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to delete retentionPolicy: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,8 +374,7 @@ export const updateRoleUsersAsync = (role, users) => async (dispatch) => {
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Role users updated'))
|
dispatch(publishAutoDismissingNotification('success', 'Role users updated'))
|
||||||
dispatch(syncRole(role, data))
|
dispatch(syncRole(role, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to update role: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to update role: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,8 +384,7 @@ export const updateRolePermissionsAsync = (role, permissions) => async (dispatch
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Role permissions updated'))
|
dispatch(publishAutoDismissingNotification('success', 'Role permissions updated'))
|
||||||
dispatch(syncRole(role, data))
|
dispatch(syncRole(role, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to update role: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to update role: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,8 +394,7 @@ export const updateUserPermissionsAsync = (user, permissions) => async (dispatch
|
||||||
dispatch(publishAutoDismissingNotification('success', 'User permissions updated'))
|
dispatch(publishAutoDismissingNotification('success', 'User permissions updated'))
|
||||||
dispatch(syncUser(user, data))
|
dispatch(syncUser(user, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to update user: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to update user: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,8 +404,7 @@ export const updateUserRolesAsync = (user, roles) => async (dispatch) => {
|
||||||
dispatch(publishAutoDismissingNotification('success', 'User roles updated'))
|
dispatch(publishAutoDismissingNotification('success', 'User roles updated'))
|
||||||
dispatch(syncUser(user, data))
|
dispatch(syncUser(user, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to update user: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to update user: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +414,6 @@ export const updateUserPasswordAsync = (user, password) => async (dispatch) => {
|
||||||
dispatch(publishAutoDismissingNotification('success', 'User password updated'))
|
dispatch(publishAutoDismissingNotification('success', 'User password updated'))
|
||||||
dispatch(syncUser(user, data))
|
dispatch(syncUser(user, data))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to update user: ${error.data.message}`))
|
||||||
dispatch(publishNotification('error', `Failed to update user: ${error.data.message}`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
deleteDashboardCell as deleteDashboardCellAJAX,
|
deleteDashboardCell as deleteDashboardCellAJAX,
|
||||||
} from 'src/dashboards/apis'
|
} from 'src/dashboards/apis'
|
||||||
|
|
||||||
import {publishNotification} from 'shared/actions/notifications'
|
|
||||||
import {publishAutoDismissingNotification} from 'shared/dispatchers'
|
import {publishAutoDismissingNotification} from 'shared/dispatchers'
|
||||||
import {errorThrown} from 'shared/actions/errors'
|
import {errorThrown} from 'shared/actions/errors'
|
||||||
|
|
||||||
|
@ -149,9 +148,8 @@ export const deleteDashboardAsync = (dashboard) => async (dispatch) => {
|
||||||
await deleteDashboardAJAX(dashboard)
|
await deleteDashboardAJAX(dashboard)
|
||||||
dispatch(publishAutoDismissingNotification('success', 'Dashboard deleted successfully.'))
|
dispatch(publishAutoDismissingNotification('success', 'Dashboard deleted successfully.'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error, `Failed to delete dashboard: ${error.data.message}.`))
|
||||||
dispatch(deleteDashboardFailed(dashboard))
|
dispatch(deleteDashboardFailed(dashboard))
|
||||||
dispatch(publishNotification('error', `Failed to delete dashboard: ${error.data.message}.`))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +170,6 @@ export const deleteDashboardCellAsync = (cell) => async (dispatch) => {
|
||||||
dispatch(deleteDashboardCell(cell))
|
dispatch(deleteDashboardCell(cell))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(errorThrown(error))
|
dispatch(errorThrown(error))
|
||||||
console.error(error)
|
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export const errorThrown = (error) => ({
|
export const errorThrown = (error, altText) => ({
|
||||||
type: 'ERROR_THROWN',
|
type: 'ERROR_THROWN',
|
||||||
error,
|
error,
|
||||||
|
altText,
|
||||||
})
|
})
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const fetchTimeSeriesAsync = async ({source, db, rp, query}, editQuerySta
|
||||||
const {data} = await proxy({source, db, rp, query: query.text})
|
const {data} = await proxy({source, db, rp, query: query.text})
|
||||||
return handleSuccess(data, query, editQueryStatus)
|
return handleSuccess(data, query, editQueryStatus)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorThrown(error) // use errorsMiddleware to catch 403s first, otherwise query --> config --> error.status will be error obj
|
errorThrown(error) // TODO: use errorsMiddleware to catch 403s first, otherwise query --> config --> error.status will be error obj
|
||||||
handleError(error, query, editQueryStatus)
|
handleError(error, query, editQueryStatus)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ let allowNotifications = true // eslint-disable-line
|
||||||
|
|
||||||
const errorsMiddleware = store => next => action => {
|
const errorsMiddleware = store => next => action => {
|
||||||
if (action.type === 'ERROR_THROWN') {
|
if (action.type === 'ERROR_THROWN') {
|
||||||
const {error, error: {status, auth}} = action
|
const {error, error: {status, auth}, altText} = action
|
||||||
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ const errorsMiddleware = store => next => action => {
|
||||||
} else {
|
} else {
|
||||||
store.dispatch(notify('error', 'Please login to use Chronograf.'))
|
store.dispatch(notify('error', 'Please login to use Chronograf.'))
|
||||||
}
|
}
|
||||||
|
} else if (altText) {
|
||||||
|
store.dispatch(notify('error', altText))
|
||||||
} else {
|
} else {
|
||||||
store.dispatch(notify('error', 'Cannot communicate with server.'))
|
store.dispatch(notify('error', 'Cannot communicate with server.'))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue