render 404 for nonexistent resources (#2341)

This commit is contained in:
IMRAN KHAN 2019-06-17 12:17:27 +05:30 committed by Rikin Kachhia
parent 86c5348959
commit d6a071bd83
29 changed files with 350 additions and 340 deletions

View File

@ -7,27 +7,39 @@ import {
} from '../Services/Metadata/Actions';
import Spinner from '../Common/Spinner/Spinner';
import { Link } from 'react-router';
import Helmet from 'react-helmet';
import PageNotFound, { NotFoundError } from './PageNotFound';
import RuntimeError from './RuntimeError';
class ErrorBoundary extends React.Component {
initialState = {
hasError: false,
info: null,
error: null,
type: '500',
};
constructor(props) {
super(props);
this.state = { hasError: false, info: null, error: null };
this.state = this.initialState;
}
resetState = () => {
this.setState({ hasError: false, info: null, error: null });
this.setState({ ...this.initialState });
};
componentDidCatch(error, info) {
this.setState({ hasError: true, info: info, error: error });
// TODO logErrorToMyService(error, info);
const { dispatch } = this.props;
// for invalid path segment errors
if (error instanceof NotFoundError) {
this.setState({
type: '404',
});
}
this.setState({ hasError: true, info: info, error: error });
dispatch(loadInconsistentObjects(true)).then(() => {
if (this.props.metadata.inconsistentObjects.length > 0) {
if (!isMetadataStatusPage()) {
@ -41,56 +53,22 @@ class ErrorBoundary extends React.Component {
}
render() {
const errorImage = require('./error-logo.png');
const styles = require('./ErrorPage.scss');
const { metadata } = this.props;
const { hasError, type } = this.state;
if (this.state.hasError && metadata.ongoingRequest) {
if (hasError && metadata.ongoingRequest) {
return (
<div>
{' '}
<Spinner />{' '}
<Spinner />
</div>
);
}
if (this.state.hasError) {
return (
<div className={styles.viewContainer}>
<Helmet title="Error | Hasura" />
<div className={'container ' + styles.centerContent}>
<div className={'row ' + styles.message}>
<div className="col-xs-8">
<h1>Error</h1>
<br />
<div>
Something went wrong. Head back{' '}
<Link to="/" onClick={this.resetState}>
Home
</Link>
.
</div>
<br />
<div>
You can report this issue on our{' '}
<a href="https://github.com/hasura/graphql-engine/issues">
GitHub
</a>{' '}
or chat with us on{' '}
<a href="http://discord.gg/hasura">Discord</a>
</div>
</div>
<div className="col-xs-4">
<img
src={errorImage}
className="img-responsive"
name="hasura"
title="Something went wrong!"
/>
</div>
</div>
</div>
</div>
if (hasError) {
return type === '404' ? (
<PageNotFound resetCallback={this.resetState} />
) : (
<RuntimeError resetCallback={this.resetState} />
);
}

View File

@ -5,11 +5,15 @@ import { connect } from 'react-redux';
import { Link } from 'react-router';
import Helmet from 'react-helmet';
export class NotFoundError extends Error {}
class PageNotFound extends Component {
render() {
const errorImage = require('./error-logo.png');
const styles = require('./ErrorPage.scss');
const { resetCallback } = this.props;
return (
<div className={styles.viewContainer}>
<Helmet title="404 - Page Not Found | Hasura" />
@ -19,7 +23,11 @@ class PageNotFound extends Component {
<h1>404</h1>
<br />
<div>
This page doesn't exist. Head back <Link to="/">Home</Link>.
This page doesn't exist. Head back{' '}
<Link to="/" onClick={resetCallback}>
Home
</Link>
.
</div>
</div>
<div className="col-xs-4">
@ -39,6 +47,7 @@ class PageNotFound extends Component {
PageNotFound.propTypes = {
dispatch: PropTypes.func.isRequired,
resetCallback: PropTypes.func.isRequired,
};
export default connect()(PageNotFound);

View File

@ -0,0 +1,60 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import Helmet from 'react-helmet';
class RuntimeError extends Component {
render() {
const errorImage = require('./error-logo.png');
const styles = require('./ErrorPage.scss');
const { resetCallback } = this.props;
return (
<div className={styles.viewContainer}>
<Helmet title="Error | Hasura" />
<div className={'container ' + styles.centerContent}>
<div className={'row ' + styles.message}>
<div className="col-xs-8">
<h1>Error</h1>
<br />
<div>
Something went wrong. Head back{' '}
<Link to="/" onClick={resetCallback}>
Home
</Link>
.
</div>
<br />
<div>
You can report this issue on our{' '}
<a href="https://github.com/hasura/graphql-engine/issues">
GitHub
</a>{' '}
or chat with us on{' '}
<a href="http://discord.gg/hasura">Discord</a>
</div>
</div>
<div className="col-xs-4">
<img
src={errorImage}
className="img-responsive"
name="hasura"
title="Something went wrong!"
/>
</div>
</div>
</div>
</div>
);
}
}
RuntimeError.propTypes = {
dispatch: PropTypes.func.isRequired,
resetCallback: PropTypes.func.isRequired,
};
export default connect()(RuntimeError);

View File

@ -197,8 +197,9 @@ const addResolver = () => {
const customOnSuccess = data => {
Promise.all([
dispatch({ type: RESET }),
dispatch(push(`${prefixUrl}/manage/${resolveObj.name}/details`)),
dispatch(fetchResolvers()),
dispatch(fetchResolvers()).then(() => {
dispatch(push(`${prefixUrl}/manage/${resolveObj.name}/details`));
}),
dispatch({ type: getHeaderEvents.RESET_HEADER, data: data }),
]);
};
@ -304,21 +305,19 @@ const deleteResolver = () => {
const modifyResolver = () => {
return (dispatch, getState) => {
const currState = getState().customResolverData.addData;
const remoteSchemaName = currState.name.trim().replace(/ +/g, '');
// const url = Endpoints.getSchema;
const upQueryArgs = [];
const downQueryArgs = [];
const migrationName =
'update_remote_schema_' + currState.name.trim().replace(/ +/g, '');
const schemaName = currState.name.trim().replace(/ +/g, '');
const migrationName = 'update_remote_schema_' + remoteSchemaName;
const deleteResolverUp = {
type: 'remove_remote_schema',
args: {
name: currState.editState.originalName,
},
};
const trimmedName = currState.name.trim().replace(/ +/g, '');
const resolveObj = {
name: trimmedName,
name: remoteSchemaName,
definition: {
url: currState.manualUrl,
url_from_env: currState.envName,
@ -349,7 +348,7 @@ const modifyResolver = () => {
const deleteResolverDown = {
type: 'remove_remote_schema',
args: {
name: trimmedName,
name: remoteSchemaName,
},
};
const resolveDownObj = {
@ -396,15 +395,12 @@ const modifyResolver = () => {
const customOnSuccess = data => {
// dispatch({ type: REQUEST_SUCCESS });
Promise.all([
dispatch({ type: RESET, data: data }),
dispatch(fetchResolvers()),
]).then(() => {
return Promise.all([
dispatch(fetchResolver(schemaName)),
dispatch(push(`${prefixUrl}/manage/${trimmedName}/details`)),
]);
dispatch({ type: RESET, data: data });
dispatch(push(`${prefixUrl}/manage/schemas`)); // Hack to avoid 404
dispatch(fetchResolvers()).then(() => {
dispatch(push(`${prefixUrl}/manage/${remoteSchemaName}/details`));
});
dispatch(fetchResolver(remoteSchemaName));
};
const customOnError = error => {
Promise.all([dispatch({ type: MODIFY_RESOLVER_FAIL, data: error })]);
@ -426,149 +422,6 @@ const modifyResolver = () => {
};
};
/*
const modifyResolver = () => {
return (dispatch, getState) => {
const currState = getState().customResolverData.addData;
// const url = Endpoints.getSchema;
let upQueryArgs = [];
let downQueryArgs = [];
const migrationName = 'update_add_schema_' + currState.name.trim();
const schemaName = currState.name.trim();
const deleteResolverUp = {
type: 'remove_remote_schema',
args: {
name: currState.editState.originalName,
},
};
upQueryArgs.push(deleteResolverUp);
// Delete the new one and create the old one
const resolveDownObj = {
name: currState.editState.originalName,
url: currState.editState.originalUrl,
url_from_env: currState.editState.originalEnvUrl,
headers: [],
};
resolveDownObj.headers = [...currState.editState.originalHeaders];
if (resolveDownObj.url) {
delete resolveDownObj.url_from_env;
} else {
delete resolveDownObj.url;
}
const createResolverDown = {
type: 'add_remote_schema',
args: {
...resolveDownObj,
},
};
downQueryArgs.push(createResolverDown);
let upQuery = {
type: 'bulk',
args: upQueryArgs,
};
let downQuery = {
type: 'bulk',
args: downQueryArgs,
};
const requestMsg = 'Modifying schema...';
const successMsg = 'Schema modified';
const errorMsg = 'Modify schema failed';
const customOnSuccess = () => {
// dispatch({ type: REQUEST_SUCCESS });
// Do the modify thing here
upQueryArgs = [];
downQueryArgs = [];
const resolveObj = {
name: currState.name.trim(),
url: currState.manualUrl,
url_from_env: currState.envName,
headers: [],
};
resolveObj.headers = [
...getReqHeader(getState().customResolverData.headerData.headers),
];
if (resolveObj.url) {
delete resolveObj.url_from_env;
} else {
delete resolveObj.url;
}
const createResolverUp = {
type: 'add_remote_schema',
args: {
...resolveObj,
},
};
upQueryArgs.push(createResolverUp);
const deleteResolverDown = {
type: 'remove_remote_schema',
args: {
name: currState.name,
},
};
downQueryArgs.push(deleteResolverDown);
upQuery = {
type: 'bulk',
args: upQueryArgs,
};
downQuery = {
type: 'bulk',
args: downQueryArgs,
};
const tOnSuccess = () => {
Promise.all([
dispatch({ type: RESET }),
dispatch(fetchResolvers()),
]).then(() => {
return dispatch(fetchResolver(schemaName));
});
};
const tOnError = error => {
Promise.all([dispatch({ type: MODIFY_RESOLVER_FAIL, data: error })]);
};
return dispatch(
makeRequest(
upQuery.args,
downQuery.args,
migrationName,
tOnSuccess,
tOnError,
requestMsg,
successMsg,
errorMsg
)
);
};
const customOnError = error => {
Promise.all([dispatch({ type: MODIFY_RESOLVER_FAIL, data: error })]);
};
dispatch({ type: MODIFYING_RESOLVER });
return dispatch(
makeRequest(
upQuery.args,
downQuery.args,
migrationName,
customOnSuccess,
customOnError,
requestMsg
)
);
};
};
*/
const addResolverReducer = (state = addState, action) => {
switch (action.type) {
case MANUAL_URL_CHANGED:

View File

@ -17,6 +17,8 @@ import Button from '../../../Common/Button/Button';
import { appPrefix, pageTitle } from '../constants';
import { NotFoundError } from '../../../Error/PageNotFound';
import globals from '../../../../Globals';
const prefixUrl = globals.urlPrefix + appPrefix;
@ -102,6 +104,15 @@ class Edit extends React.Component {
}
render() {
const currentResolver = this.props.allResolvers.find(
r => r.name === this.props.params.resolverName
);
if (!currentResolver) {
// throw a 404 exception
throw new NotFoundError();
}
const styles = require('../CustomResolver.scss');
const { isFetching, isRequesting, editState } = this.props;
@ -234,6 +245,7 @@ const mapStateToProps = state => {
return {
...state.customResolverData.addData,
...state.customResolverData.headerData,
allResolvers: state.customResolverData.listData.resolvers,
dataHeaders: { ...state.tables.dataHeaders },
};
};

View File

@ -13,6 +13,8 @@ import ReloadMetadata from '../../Metadata/MetadataOptions/ReloadMetadata';
import { appPrefix } from '../constants';
import { NotFoundError } from '../../../Error/PageNotFound';
import globals from '../../../../Globals';
const prefixUrl = globals.urlPrefix + appPrefix;
@ -49,6 +51,15 @@ class ViewStitchedSchema extends React.Component {
}
render() {
const currentResolver = this.props.allResolvers.find(
r => r.name === this.props.params.resolverName
);
if (!currentResolver) {
// throw a 404 exception
throw new NotFoundError();
}
const styles = require('../CustomResolver.scss');
const { resolverName } = this.props.params;
@ -171,6 +182,7 @@ const mapStateToProps = state => {
return {
...state.customResolverData.addData,
...state.customResolverData.headerData,
allResolvers: state.customResolverData.listData.resolvers,
dataHeaders: { ...state.tables.dataHeaders },
};
};

View File

@ -395,8 +395,10 @@ const fetchFunctionInit = () => (dispatch, getState) => {
);
};
const updateCurrentSchema = schemaName => dispatch => {
dispatch(push(`${globals.urlPrefix}/data/schema/${schemaName}`));
const updateCurrentSchema = (schemaName, redirect = true) => dispatch => {
if (redirect) {
dispatch(push(`${globals.urlPrefix}/data/schema/${schemaName}`));
}
Promise.all([
dispatch({ type: UPDATE_CURRENT_SCHEMA, currentSchema: schemaName }),

View File

@ -7,6 +7,7 @@ import PageContainer from '../../Common/Layout/PageContainer/PageContainer';
import DataSubSidebar from './DataSubSidebar';
import { updateCurrentSchema } from './DataActions';
import { NotFoundError } from '../../Error/PageNotFound';
const sectionPrefix = '/data';
@ -20,6 +21,13 @@ const DataPageContainer = ({
}) => {
const styles = require('../../Common/TableCommon/Table.scss');
if (!schemaList.map(s => s.schema_name).includes(currentSchema)) {
dispatch(updateCurrentSchema('public', false));
// throw a 404 exception
throw new NotFoundError();
}
const currentLocation = location.pathname;
let migrationTab = null;
@ -42,6 +50,14 @@ const DataPageContainer = ({
dispatch(updateCurrentSchema(e.target.value));
};
const getSchemaOptions = () => {
return schemaList.map(s => (
<option key={s.schema_name} value={s.schema_name}>
{s.schema_name}
</option>
));
};
const sidebarContent = (
<ul>
<li
@ -60,11 +76,7 @@ const DataPageContainer = ({
value={currentSchema}
className={styles.changeSchema + ' form-control'}
>
{schemaList.map(s => (
<option key={s.schema_name} value={s.schema_name}>
{s.schema_name}
</option>
))}
{getSchemaOptions()}
</select>
</div>
</div>

View File

@ -23,12 +23,16 @@ import {
} from '../customFunctionReducer';
import { SET_SQL } from '../../RawSQL/Actions';
import { NotFoundError } from '../../../../Error/PageNotFound';
class ModifyCustomFunction extends React.Component {
constructor() {
super();
this.state = {};
this.state.deleteConfirmationError = null;
this.state = {
deleteConfirmationError: null,
funcFetchCompleted: false,
};
}
componentDidMount() {
@ -37,7 +41,11 @@ class ModifyCustomFunction extends React.Component {
this.props.dispatch(push(prefixUrl));
}
Promise.all([
this.props.dispatch(fetchCustomFunction(functionName, schema)),
this.props
.dispatch(fetchCustomFunction(functionName, schema))
.then(() => {
this.setState({ funcFetchCompleted: true });
}),
]);
}
@ -48,12 +56,16 @@ class ModifyCustomFunction extends React.Component {
schema !== nextProps.params.schema
) {
Promise.all([
this.props.dispatch(
fetchCustomFunction(
nextProps.params.functionName,
nextProps.params.schema
this.props
.dispatch(
fetchCustomFunction(
nextProps.params.functionName,
nextProps.params.schema
)
)
),
.then(() => {
this.setState({ funcFetchCompleted: true });
}),
]);
}
}
@ -108,6 +120,11 @@ class ModifyCustomFunction extends React.Component {
isFetching,
} = this.props.functions;
if (this.state.funcFetchCompleted && !functionName) {
// throw a 404 exception
throw new NotFoundError();
}
const { migrationMode } = this.props;
const baseUrl = `${appPrefix}/schema/${schema}/functions/${functionName}`;
@ -182,6 +199,7 @@ class ModifyCustomFunction extends React.Component {
url: '',
});
}
return (
<div className={'col-xs-8' + ' ' + styles.modifyWrapper}>
<Helmet

View File

@ -10,8 +10,6 @@ import { pageTitle, appPrefix } from '../Modify/constants';
import tabInfo from '../Modify/tabInfo';
import globals from '../../../../../Globals';
const prefixUrl = globals.urlPrefix + appPrefix;
import { fetchCustomFunction } from '../customFunctionReducer';
import {
updateSchemaInfo,
@ -19,15 +17,32 @@ import {
fetchFunctionInit,
setTable,
} from '../../DataActions';
import { NotFoundError } from '../../../../Error/PageNotFound';
const prefixUrl = globals.urlPrefix + appPrefix;
class Permission extends React.Component {
constructor() {
super();
this.state = {
funcFetchCompleted: false,
};
}
componentDidMount() {
const { functionName, schema } = this.props.params;
if (!functionName) {
this.props.dispatch(push(prefixUrl));
}
Promise.all([
this.props.dispatch(fetchCustomFunction(functionName, schema)),
this.props
.dispatch(fetchCustomFunction(functionName, schema))
.then(() => {
this.setState({ funcFetchCompleted: true });
}),
]);
}
render() {
@ -39,6 +54,11 @@ class Permission extends React.Component {
setOffTableSchema,
} = this.props.functions;
if (this.state.funcFetchCompleted && !functionName) {
// throw a 404 exception
throw new NotFoundError();
}
const { dispatch } = this.props;
const baseUrl = `${appPrefix}/schema/${schema}/functions/${functionName}`;

View File

@ -157,10 +157,9 @@ const fetchCustomFunction = (functionName, schema) => {
});
return Promise.resolve();
}
return dispatch(_push('/'));
},
error => {
console.error('Failed to fetch resolver' + JSON.stringify(error));
console.error('Failed to fetch function' + JSON.stringify(error));
return dispatch({ type: CUSTOM_FUNCTION_FETCH_FAIL, data: error });
}
);
@ -276,12 +275,9 @@ const unTrackCustomFunction = () => {
const errorMsg = 'Delete custom function failed';
const customOnSuccess = () => {
// dispatch({ type: REQUEST_SUCCESS });
Promise.all([
dispatch({ type: RESET }),
dispatch(_push('/')),
dispatch(fetchTrackedFunctions()),
]);
dispatch(_push(`/schema/${currentSchema}`));
dispatch({ type: RESET });
dispatch(fetchTrackedFunctions());
};
const customOnError = error => {
Promise.all([

View File

@ -43,10 +43,11 @@ export const createNewSchema = (schemaName, successCb, errorCb) => {
const errorMsg = 'Error creating schema';
const customOnSuccess = () => {
dispatch(fetchSchemaList());
if (successCb) {
successCb();
}
dispatch(fetchSchemaList()).then(() => {
if (successCb) {
successCb();
}
});
};
const customOnError = () => {
if (errorCb) {

View File

@ -133,9 +133,11 @@ class Schema extends Component {
};
const getCurrentSchemaSection = () => {
const schemaOptions = schemaList.map(s => {
return <option key={s.schema_name}>{s.schema_name}</option>;
});
const getSchemaOptions = () => {
return schemaList.map(s => (
<option key={s.schema_name}>{s.schema_name}</option>
));
};
const getCreateSchemaSection = () => {
let createSchemaSection = null;
@ -262,7 +264,7 @@ class Schema extends Component {
}
value={currentSchema}
>
{schemaOptions}
{getSchemaOptions()}
</select>
</div>
<div className={styles.display_inline + ' ' + styles.add_mar_left}>

View File

@ -12,7 +12,8 @@ import { setTable } from '../DataActions';
import TableHeader from '../TableCommon/TableHeader';
import ViewHeader from './ViewHeader';
import ViewRows from './ViewRows';
import { replace } from 'react-router-redux';
import { NotFoundError } from '../../../Error/PageNotFound';
const genHeadings = headings => {
if (headings.length === 0) {
@ -146,7 +147,7 @@ class ViewTable extends Component {
query,
curFilter,
rows,
count, // eslint-disable-line no-unused-vars
count,
activePath,
migrationMode,
ongoingRequest,
@ -159,16 +160,18 @@ class ViewTable extends Component {
manualTriggers = [],
triggeredRow,
triggeredFunction,
} = this.props; // eslint-disable-line no-unused-vars
} = this.props;
// check if table exists
const currentTable = schemas.find(
s => s.table_name === tableName && s.table_schema === currentSchema
);
if (!currentTable) {
// dispatch a 404 route
dispatch(replace('/404'));
// throw a 404 exception
throw new NotFoundError();
}
// Is this a view
const isView = currentTable.table_type !== 'BASE TABLE';

View File

@ -10,6 +10,8 @@ import { getPlaceholder, BOOLEAN, JSONB, JSONDTYPE } from '../utils';
import { getParentNodeByClass } from '../../../../utils/domFunctions';
import { NotFoundError } from '../../../Error/PageNotFound';
class InsertItem extends Component {
constructor() {
super();
@ -48,6 +50,15 @@ class InsertItem extends Component {
} = this.props;
const styles = require('../../../Common/TableCommon/Table.scss');
// check if table exists
const currentTable = schemas.find(
s => s.table_name === tableName && s.table_schema === currentSchema
);
if (!currentTable) {
// throw a 404 exception
throw new NotFoundError();
}
const _columns = schemas.find(
x => x.table_name === tableName && x.table_schema === currentSchema
).columns;

View File

@ -315,14 +315,14 @@ const saveForeignKeys = (index, tableSchema, columns) => {
alter table "${schemaName}"."${tableName}" drop constraint "${generatedConstraintName}",
add constraint "${constraintName}"
foreign key (${Object.keys(oldConstraint.column_mapping)
.map(lc => `"${lc}"`)
.join(', ')})
.map(lc => `"${lc}"`)
.join(', ')})
references "${oldConstraint.ref_table_table_schema}"."${
oldConstraint.ref_table
}"
oldConstraint.ref_table
}"
(${Object.values(oldConstraint.column_mapping)
.map(rc => `"${rc}"`)
.join(', ')})
.map(rc => `"${rc}"`)
.join(', ')})
on update ${pgConfTypes[oldConstraint.on_update]}
on delete ${pgConfTypes[oldConstraint.on_delete]};
`;
@ -571,10 +571,11 @@ const deleteTableSql = tableName => {
const errorMsg = 'Deleting table failed';
const customOnSuccess = () => {
dispatch(updateSchemaInfo()).then(() => {
dispatch(_push('/'));
});
dispatch(updateSchemaInfo());
dispatch(_push('/'));
};
const customOnError = err => {
dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: err });
};
@ -1206,24 +1207,24 @@ const saveColumnChangesSql = (colName, column) => {
const schemaChangesUp =
originalColType !== colType
? [
{
type: 'run_sql',
args: {
sql: columnChangesUpQuery,
},
{
type: 'run_sql',
args: {
sql: columnChangesUpQuery,
},
]
},
]
: [];
const schemaChangesDown =
originalColType !== colType
? [
{
type: 'run_sql',
args: {
sql: columnChangesDownQuery,
},
{
type: 'run_sql',
args: {
sql: columnChangesDownQuery,
},
]
},
]
: [];
/* column default up/down migration */

View File

@ -24,7 +24,7 @@ import TableCommentEditor from './TableCommentEditor';
import ForeignKeyEditor from './ForeignKeyEditor';
import UniqueKeyEditor from './UniqueKeyEditor';
import styles from './ModifyTable.scss';
import { replace } from 'react-router-redux';
import { NotFoundError } from '../../../Error/PageNotFound';
class ModifyTable extends React.Component {
componentDidMount() {
@ -62,8 +62,8 @@ class ModifyTable extends React.Component {
t => t.table_name === tableName && t.table_schema === currentSchema
);
if (!tableSchema) {
dispatch(replace('/404'));
return null;
// throw a 404 exception
throw new NotFoundError();
}
const tableComment = tableSchema.comment;

View File

@ -12,6 +12,7 @@ import TableCommentEditor from './TableCommentEditor';
import { ordinalColSort } from '../utils';
import { setTable } from '../DataActions';
import Button from '../../../Common/Button/Button';
import { NotFoundError } from '../../../Error/PageNotFound';
class ModifyView extends Component {
componentDidMount() {
@ -45,7 +46,13 @@ class ModifyView extends Component {
const tableSchema = allSchemas.find(
t => t.table_name === tableName && t.table_schema === currentSchema
); // eslint-disable-line no-unused-vars
);
if (!tableSchema) {
// throw a 404 exception
throw new NotFoundError();
}
const tableComment = tableSchema.comment;
let alert = null;

View File

@ -48,6 +48,8 @@ import { allOperators, getLegacyOperator } from './PermissionBuilder/utils';
import Button from '../../../Common/Button/Button';
import { defaultPresetsState } from '../DataState';
import { NotFoundError } from '../../../Error/PageNotFound';
class Permissions extends Component {
constructor() {
super();
@ -66,16 +68,6 @@ class Permissions extends Component {
componentDidMount() {
this.props.dispatch({ type: RESET });
const currentTableSchema = this.props.allSchemas.find(
t =>
t.table_name === this.props.tableName &&
t.table_schema === this.props.currentSchema
);
if (!currentTableSchema) {
return;
}
this.props.dispatch(setTable(this.props.tableName));
}
@ -94,6 +86,17 @@ class Permissions extends Component {
currentSchema,
} = this.props;
const currentTableSchema = this.props.allSchemas.find(
t =>
t.table_name === this.props.tableName &&
t.table_schema === this.props.currentSchema
);
if (!currentTableSchema) {
// throw a 404 exception
throw new NotFoundError();
}
const styles = require('../TableModify/ModifyTable.scss');
const getAllRoles = allTableSchemas => {

View File

@ -21,6 +21,7 @@ import Button from '../../../Common/Button/Button';
import AddManualRelationship from './AddManualRelationship';
import suggestedRelationshipsRaw from './autoRelations';
import RelationshipEditor from './RelationshipEditor';
import { NotFoundError } from '../../../Error/PageNotFound';
const addRelationshipCellView = (
dispatch,
@ -328,6 +329,12 @@ class Relationships extends Component {
const tableSchema = allSchemas.find(
t => t.table_name === tableName && t.table_schema === currentSchema
);
if (!tableSchema) {
// throw a 404 exception
throw new NotFoundError();
}
let alert = null;
if (ongoingRequest) {
alert = (

View File

@ -7,6 +7,7 @@ import { getObjArrRelList } from './utils';
import { setTable, UPDATE_REMOTE_SCHEMA_MANUAL_REL } from '../DataActions';
import AddManualRelationship from './AddManualRelationship';
import RelationshipEditor from './RelationshipEditor';
import { NotFoundError } from '../../../Error/PageNotFound';
class RelationshipsView extends Component {
componentDidMount() {
@ -40,6 +41,12 @@ class RelationshipsView extends Component {
const tableSchema = allSchemas.find(
t => t.table_name === tableName && t.table_schema === currentSchema
);
if (!tableSchema) {
// throw a 404 exception
throw new NotFoundError();
}
let alert = null;
if (ongoingRequest) {
alert = (

View File

@ -469,6 +469,7 @@ const deleteTrigger = triggerName => {
// dispatch({ type: REQUEST_SUCCESS });
dispatch({ type: REQUEST_COMPLETE }); // modify trigger action
dispatch(showSuccessNotification('Trigger Deleted'));
dispatch(push('/manage/triggers'));
// remove this trigger from state
const existingTriggers = getState().triggers.triggerList.filter(
trigger => trigger.name !== triggerName
@ -477,7 +478,6 @@ const deleteTrigger = triggerName => {
type: LOAD_TRIGGER_LIST,
triggerList: existingTriggers,
});
dispatch(push('/manage/triggers'));
return;
};
const customOnError = () => {

View File

@ -3,7 +3,6 @@ import TableHeader from '../TableCommon/TableHeader';
import styles from './ModifyEvent.scss';
import { getTableColumns } from '../utils';
import _push from '../push';
import Info from './Info';
import WebhookEditor from './WebhookEditor';
@ -14,6 +13,8 @@ import ActionButtons from './ActionButtons';
import { save, setDefaults, RESET_MODIFY_STATE } from './Actions';
import { NotFoundError } from '../../../Error/PageNotFound';
class Modify extends React.Component {
componentDidMount() {
const { dispatch } = this.props;
@ -40,8 +41,8 @@ class Modify extends React.Component {
);
if (!currentTrigger) {
dispatch(_push('/events/manage'));
return null;
// throw a 404 exception
throw new NotFoundError();
}
const {

View File

@ -34,9 +34,6 @@ const vMakeRequest = () => {
const state = getState();
const url = Endpoints.query;
const originalTrigger = getState().triggers.currentTrigger;
const triggerList = getState().triggers.triggerList;
const triggerSchema = triggerList.filter(t => t.name === originalTrigger);
const triggerName = triggerSchema[0].name;
const currentQuery = JSON.parse(JSON.stringify(state.triggers.view.query));
// count query
const countQuery = JSON.parse(JSON.stringify(state.triggers.view.query));
@ -52,7 +49,7 @@ const vMakeRequest = () => {
finalAndClause.push({ error: false });
currentQuery.columns[1].where = { $and: finalAndClause };
currentQuery.where = { name: state.triggers.currentTrigger };
countQuery.where.$and.push({ trigger_name: triggerName });
countQuery.where.$and.push({ trigger_name: originalTrigger });
} else {
// reset where for events
if (currentQuery.columns[1]) {

View File

@ -4,7 +4,7 @@ import { vSetDefaults, vMakeRequest, vExpandHeading } from './ViewActions'; // e
import { setTrigger } from '../EventActions';
import TableHeader from '../TableCommon/TableHeader';
import ViewRows from './ViewRows';
import { replace } from 'react-router-redux';
import { NotFoundError } from '../../../Error/PageNotFound';
const genHeadings = headings => {
if (headings.length === 0) {
@ -129,12 +129,13 @@ class ViewTable extends Component {
expandedRow,
} = this.props; // eslint-disable-line no-unused-vars
// check if table exists
// check if trigger exists
const currentTrigger = triggerList.find(s => s.name === triggerName);
if (!currentTrigger) {
// dispatch a 404 route
dispatch(replace('/404'));
// throw a 404 exception
throw new NotFoundError();
}
// Is this a view
const isView = false;

View File

@ -44,9 +44,6 @@ const vMakeRequest = () => {
const state = getState();
const url = Endpoints.query;
const originalTrigger = getState().triggers.currentTrigger;
const triggerList = getState().triggers.triggerList;
const triggerSchema = triggerList.filter(t => t.name === originalTrigger);
const triggerName = triggerSchema[0].name;
const currentQuery = JSON.parse(JSON.stringify(state.triggers.view.query));
// count query
const countQuery = JSON.parse(JSON.stringify(state.triggers.view.query));
@ -64,7 +61,7 @@ const vMakeRequest = () => {
currentQuery.columns[1].where = { $and: finalAndClause };
currentQuery.where = { name: state.triggers.currentTrigger };
countQuery.where.$and.push({
trigger_name: state.triggers.currentTrigger,
trigger_name: originalTrigger,
});
} else {
// reset where for events
@ -76,7 +73,7 @@ const vMakeRequest = () => {
currentQuery.where = { name: state.triggers.currentTrigger };
countQuery.where = {
$and: [
{ trigger_name: triggerName },
{ trigger_name: state.triggers.currentTrigger },
{ $or: [{ delivered: { $eq: true } }, { error: { $eq: true } }] },
],
};

View File

@ -4,7 +4,7 @@ import { vSetDefaults, vMakeRequest, vExpandHeading } from './ViewActions'; // e
import { setTrigger } from '../EventActions';
import TableHeader from '../TableCommon/TableHeader';
import ViewRows from './ViewRows';
import { replace } from 'react-router-redux';
import { NotFoundError } from '../../../Error/PageNotFound';
const genHeadings = headings => {
if (headings.length === 0) {
@ -143,8 +143,8 @@ class ViewTable extends Component {
// check if table exists
const currentTrigger = triggerList.find(s => s.name === triggerName);
if (!currentTrigger) {
// dispatch a 404 route
dispatch(replace('/404'));
// throw a 404 exception
throw new NotFoundError();
}
// Is this a view
const isView = false;

View File

@ -4,7 +4,7 @@ import { vSetDefaults, vMakeRequest, vExpandHeading } from './ViewActions'; // e
import { setTrigger } from '../EventActions';
import TableHeader from '../TableCommon/TableHeader';
import ViewRows from './ViewRows';
import { replace } from 'react-router-redux';
import { NotFoundError } from '../../../Error/PageNotFound';
const genHeadings = headings => {
if (headings.length === 0) {
@ -133,8 +133,8 @@ class ViewTable extends Component {
// check if table exists
const currentTrigger = triggerList.find(s => s.name === triggerName);
if (!currentTrigger) {
// dispatch a 404 route
dispatch(replace('/404'));
// throw a 404 exception
throw new NotFoundError();
}
// Is this a view
const isView = false;

View File

@ -28,6 +28,7 @@ import * as tooltip from '../Common/Tooltips';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import { convertDateTimeToLocale } from '../utils';
import Button from '../../../Common/Button/Button';
import { NotFoundError } from '../../../Error/PageNotFound';
class StreamingLogs extends Component {
constructor(props) {
@ -106,17 +107,16 @@ class StreamingLogs extends Component {
}
render() {
const {
triggerName,
log,
count,
dispatch,
triggerList,
} = this.props;
const { triggerName, log, count, dispatch, triggerList } = this.props;
const styles = require('../TableCommon/EventTable.scss');
// check if trigger exists
const currentTrigger = triggerList.find(s => s.name === triggerName);
if (!currentTrigger) {
// throw a 404 exception
throw new NotFoundError();
}
const invocationColumns = [
'redeliver',
@ -292,32 +292,32 @@ class StreamingLogs extends Component {
>
{finalResponse.status_code
? [
'Status Code: ',
verifySuccessStatus(finalResponse.status_code) ? (
<i
className={
styles.invocationSuccess + ' fa fa-check'
}
/>
) : (
<i
className={
styles.invocationFailure + ' fa fa-times'
}
/>
),
finalResponse.status_code,
' ',
<OverlayTrigger
placement="top"
overlay={tooltip.statusCodeDescription}
>
<i
className="fa fa-question-circle"
aria-hidden="true"
/>
</OverlayTrigger>,
]
'Status Code: ',
verifySuccessStatus(finalResponse.status_code) ? (
<i
className={
styles.invocationSuccess + ' fa fa-check'
}
/>
) : (
<i
className={
styles.invocationFailure + ' fa fa-times'
}
/>
),
finalResponse.status_code,
' ',
<OverlayTrigger
placement="top"
overlay={tooltip.statusCodeDescription}
>
<i
className="fa fa-question-circle"
aria-hidden="true"
/>
</OverlayTrigger>,
]
: null}
</div>
<AceEditor