mirror of
https://github.com/wassname/talk.git
synced 2026-09-09 11:38:08 +08:00
withQuery and withMutation support for notifyOnError (default: true)
This commit is contained in:
@@ -6,5 +6,3 @@ export { default as withEmit } from './withEmit';
|
||||
export { default as excludeIf } from './excludeIf';
|
||||
export { default as connect } from './connect';
|
||||
export { default as withMergedSettings } from './withMergedSettings';
|
||||
export { default as notifyOnMutationError } from './notifyOnMutationError';
|
||||
export { default as notifyOnDataError } from './notifyOnDataError';
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { notify } from 'coral-framework/actions/notification';
|
||||
import { branch, lifecycle, compose } from 'recompose';
|
||||
import { get } from 'lodash';
|
||||
|
||||
const notifyOnMutationError = compose(
|
||||
branch(
|
||||
({ notify }) => !notify,
|
||||
connect(null, dispatch =>
|
||||
bindActionCreators(
|
||||
{
|
||||
notify,
|
||||
},
|
||||
dispatch
|
||||
)
|
||||
)
|
||||
),
|
||||
lifecycle({
|
||||
componentWillReceiveProps(next) {
|
||||
if (
|
||||
get(next, 'data.error.message') &&
|
||||
get(this.props, 'data.error.message') !==
|
||||
get(next, 'data.error.message')
|
||||
) {
|
||||
return this.props.notify('error', next.data.error.message);
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export default notifyOnMutationError;
|
||||
@@ -1,38 +0,0 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { compose } from 'react-apollo';
|
||||
import { notify } from 'coral-framework/actions/notification';
|
||||
import { forEachError } from 'coral-framework/utils';
|
||||
import { withProps, branch } from 'recompose';
|
||||
|
||||
const notifyOnMutationError = keys =>
|
||||
compose(
|
||||
branch(
|
||||
({ notify }) => !notify,
|
||||
connect(null, dispatch =>
|
||||
bindActionCreators(
|
||||
{
|
||||
notify,
|
||||
},
|
||||
dispatch
|
||||
)
|
||||
)
|
||||
),
|
||||
withProps(ownProps =>
|
||||
keys.reduce((props, key) => {
|
||||
props[key] = async (...args) => {
|
||||
try {
|
||||
return await ownProps[key](...args);
|
||||
} catch (e) {
|
||||
forEachError(e, ({ msg }) => {
|
||||
ownProps.notify('error', msg);
|
||||
});
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
return props;
|
||||
}, {})
|
||||
)
|
||||
);
|
||||
|
||||
export default notifyOnMutationError;
|
||||
@@ -4,7 +4,11 @@ import merge from 'lodash/merge';
|
||||
import uniq from 'lodash/uniq';
|
||||
import flatten from 'lodash/flatten';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { getDefinitionName, getResponseErrors } from '../utils';
|
||||
import {
|
||||
getDefinitionName,
|
||||
getResponseErrors,
|
||||
getErrorMessages,
|
||||
} from '../utils';
|
||||
import PropTypes from 'prop-types';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
import hoistStatics from 'recompose/hoistStatics';
|
||||
@@ -27,11 +31,7 @@ class ResponseError {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a HOC with the same signature as `graphql`, that will
|
||||
* apply mutation options registered in the graphRegistry.
|
||||
*/
|
||||
export default (document, config = {}) =>
|
||||
const createHOC = (document, config, { notifyOnError = true }) =>
|
||||
hoistStatics(WrappedComponent => {
|
||||
config = {
|
||||
...config,
|
||||
@@ -46,10 +46,25 @@ export default (document, config = {}) =>
|
||||
graphql: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
notify: PropTypes.func,
|
||||
};
|
||||
|
||||
get graphqlRegistry() {
|
||||
return this.context.graphql.registry;
|
||||
}
|
||||
|
||||
notifyErrors(messages) {
|
||||
if (this.props.notify) {
|
||||
this.props.notify('error', messages);
|
||||
} else {
|
||||
console.error(
|
||||
'`notifyOnError` is set to `true` but missing `notify` property'
|
||||
);
|
||||
console.error(messages);
|
||||
}
|
||||
}
|
||||
|
||||
resolveDocument(documentOrCallback) {
|
||||
return this.context.graphql.resolveDocument(
|
||||
documentOrCallback,
|
||||
@@ -165,6 +180,11 @@ export default (document, config = {}) =>
|
||||
variables,
|
||||
error,
|
||||
});
|
||||
|
||||
// Show errors as notifications.
|
||||
if (notifyOnError) {
|
||||
this.notifyErrors(getErrorMessages(error));
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
@@ -213,3 +233,14 @@ export default (document, config = {}) =>
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Exports a HOC with the same signature as `graphql`, that will
|
||||
* apply mutation options registered in the graphRegistry.
|
||||
*/
|
||||
export default (document, config = {}) => settingsOrComponent => {
|
||||
if (typeof settingsOrComponent === 'function') {
|
||||
return createHOC(document, config, {})(settingsOrComponent);
|
||||
}
|
||||
return createHOC(document, config, settingsOrComponent);
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ import PropTypes from 'prop-types';
|
||||
import hoistStatics from 'recompose/hoistStatics';
|
||||
import { getOperationName } from 'apollo-client/queries/getFromAST';
|
||||
import throttle from 'lodash/throttle';
|
||||
import get from 'lodash/get';
|
||||
|
||||
const withSkipOnErrors = reducer => (prev, action, ...rest) => {
|
||||
if (
|
||||
@@ -36,15 +37,12 @@ function networkStatusToString(networkStatus) {
|
||||
return 'ready';
|
||||
case 8:
|
||||
return 'error';
|
||||
default:
|
||||
throw new Error(`Unknown network status ${networkStatus}`);
|
||||
}
|
||||
throw new Error(`Unknown network status ${networkStatus}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a HOC with the same signature as `graphql`, that will
|
||||
* apply query options registered in the graphRegistry.
|
||||
*/
|
||||
export default (document, config = {}) =>
|
||||
const createHOC = (document, config, { notifyOnError = true }) =>
|
||||
hoistStatics(WrappedComponent => {
|
||||
return class WithQuery extends React.Component {
|
||||
static contextTypes = {
|
||||
@@ -53,6 +51,10 @@ export default (document, config = {}) =>
|
||||
client: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
notify: PropTypes.func,
|
||||
};
|
||||
|
||||
// Lazily resolve fragments from graphRegistry to support circular dependencies.
|
||||
memoized = null;
|
||||
resolvedDocument = null;
|
||||
@@ -166,10 +168,31 @@ export default (document, config = {}) =>
|
||||
return () => this.client.networkInterface.unsubscribe(id);
|
||||
};
|
||||
|
||||
notifyErrors(messages) {
|
||||
if (this.props.notify) {
|
||||
this.props.notify('error', messages);
|
||||
} else {
|
||||
console.error(
|
||||
'`notifyOnError` is set to `true` but missing `notify` property'
|
||||
);
|
||||
console.error(messages);
|
||||
}
|
||||
}
|
||||
|
||||
nextData(data) {
|
||||
this.apolloData = data;
|
||||
this.emitWhenNeeded(data);
|
||||
|
||||
if (
|
||||
get(data, 'error.message') &&
|
||||
get(this, 'data.error.message') !== get(data, 'error.message')
|
||||
) {
|
||||
// Show errors as notifications.
|
||||
if (notifyOnError) {
|
||||
this.notifyErrors(data.error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// If data was previously set, we update it in a immutable way.
|
||||
if (this.data) {
|
||||
if (this.data.loading && !data.loading) {
|
||||
@@ -319,3 +342,14 @@ export default (document, config = {}) =>
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Exports a HOC with the same signature as `graphql`, that will
|
||||
* apply query options registered in the graphRegistry.
|
||||
*/
|
||||
export default (document, config = {}) => settingsOrComponent => {
|
||||
if (typeof settingsOrComponent === 'function') {
|
||||
return createHOC(document, config, {})(settingsOrComponent);
|
||||
}
|
||||
return createHOC(document, config, settingsOrComponent);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user