diff --git a/packages/web/src/components/ApolloProvider/index.tsx b/packages/web/src/components/ApolloProvider/index.tsx index 9b3f890e..7fe39a4a 100644 --- a/packages/web/src/components/ApolloProvider/index.tsx +++ b/packages/web/src/components/ApolloProvider/index.tsx @@ -1,11 +1,23 @@ +import * as React from 'react'; import { ApolloProvider as BaseApolloProvider } from '@apollo/client'; -import client from 'graphql/client'; +import { useSnackbar } from 'notistack'; +import client, { setLink } from 'graphql/client'; type ApolloProviderProps = { children: React.ReactNode; }; const ApolloProvider = (props: ApolloProviderProps) => { + const { enqueueSnackbar } = useSnackbar(); + + const onError = React.useCallback((message) => { + enqueueSnackbar(message, { variant: 'error' }); + }, [enqueueSnackbar]); + + React.useEffect(() => { + setLink({ onError }) + }, [onError]); + return ( ); diff --git a/packages/web/src/graphql/client.ts b/packages/web/src/graphql/client.ts index bb0b0d71..0be149ab 100644 --- a/packages/web/src/graphql/client.ts +++ b/packages/web/src/graphql/client.ts @@ -1,10 +1,23 @@ import { ApolloClient } from '@apollo/client'; import cache from './cache'; +import createLink from './link'; import appConfig from 'config/app'; +type CreateClientOptions = { + onError?: (message: string) => void; +}; + const client = new ApolloClient({ - uri: appConfig.graphqlUrl, - cache + cache, + link: createLink({ uri: appConfig.graphqlUrl }) }); +export function setLink({ onError }: CreateClientOptions) { + const link = createLink({ uri: appConfig.graphqlUrl, onError }); + + client.setLink(link); + + return client; +}; + export default client; diff --git a/packages/web/src/graphql/link.ts b/packages/web/src/graphql/link.ts new file mode 100644 index 00000000..7c3dc248 --- /dev/null +++ b/packages/web/src/graphql/link.ts @@ -0,0 +1,31 @@ +import { HttpLink, from } from "@apollo/client"; +import { onError } from "@apollo/client/link/error"; + +type CreateLinkOptions = { + uri: string; + onError?: (message: string) => void; +}; + +const createHttpLink = (uri: CreateLinkOptions['uri']) => new HttpLink({ uri }); + +const createErrorLink = (callback: CreateLinkOptions['onError']) => onError(({ graphQLErrors, networkError }) => { + if (graphQLErrors) + graphQLErrors.forEach(({ message, locations, path }) => { + callback?.(message); + + console.log( + `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`, + ); + }); + + if (networkError) { + callback?.(networkError.toString()) + console.log(`[Network error]: ${networkError}`); + } +}); + +const createLink = ({ uri, onError = function() {} }: CreateLinkOptions) => { + return from([createErrorLink(onError), createHttpLink(uri)]); +}; + +export default createLink; diff --git a/packages/web/src/index.tsx b/packages/web/src/index.tsx index b952c68b..1cb82623 100644 --- a/packages/web/src/index.tsx +++ b/packages/web/src/index.tsx @@ -10,19 +10,19 @@ import routes from 'routes'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( - - - - - - - {routes} - - - - - - , + + + + + + + {routes} + + + + + + , document.getElementById('root') )