Apollo Link middleware to enrich SentryJS events with GraphQL data.
yarn add apollo-link-sentry
Turn this:
Into this:
Initialize Sentry as you would normally. Then, add apollo-link-sentry
to your Apollo Client's link
array:
import { SentryLink } from 'apollo-link-sentry';
const client = new ApolloClient({
link: ApolloLink.from([
new SentryLink(/* See options */),
new HttpLink({ uri: 'http://localhost:4000' }),
]),
cache: new InMemoryCache(),
});
const defaultOptions = {
/**
* Set the Sentry `transaction` to the `operationName` of the query / mutation. Note that this
* only works if the transaction is not overwritten later in your app.
*/
setTransaction: true,
/**
* Narrow Sentry's fingerprint by appending the operation's name to Sentry's {{default}} key.
* It works in such a way that only the last operation is added, not every operation that's been
* through the link. Note that if you override this somewhere else in your app, it is possible
* that the value set by `apollo-link-sentry` is overwritten.
*/
setFingerprint: true,
breadcrumb: {
/**
* Set to false to disable attaching GraphQL operations as breadcrumbs. If only this breadcrumb
* option is toggled, the breadcrumb will only show the operation name and it's type.
*/
enable: true,
/**
* Include the query / mutation string in the breadcrumb.
*/
includeQuery: false,
/**
* Include the entire Apollo cache in the breadcrumb. It is not recommended to enable this
* option in production environment, for several reasons, see "Be careful what you include".
* This option is specifically useful for debugging purposes, but when applied in combination
* with `beforeBreadcrumb` can also be used in production.
*/
includeCache: false,
/**
* Include the operation's variables in the breadcrumb. Again, be careful what you include,
* or apply a filter.
*/
includeVariables: false,
/**
* Include the operation's fetch result in the breadcrumb.
*/
includeResponse: false,
/**
* If an error is received, it can be included in the breadcrumb. Regardless of this option,
* the breadcrumb's type is set to error to reflect a failed operation in the Sentry UI.
*/
includeError: false,
/**
* Include context keys as extra data in the breadcrumb. Accepts dot notation.
* The data is stringified and formatted. Can be used to include headers for instance.
*/
includeContextKeys: [],
},
/**
* Provide a callback function which receives an instance of this package's Operation class
* Only operations that pass the test are sent to Sentry. Leave undefined if you want all
* operations to pass. See PR #9 for more details.
*/
filter: (operation) => true,
/**
* Provide a callback function which receives an instance of this package's OperationBreadcrumb class
* Use it to modify the data that is added to the breadcrumb. Leave undefined if you want all
* data to be included. Very useful in combination with options like includeVariables and includeContextKeys.
*/
beforeBreadcrumb: (breadcrumb) => breadcrumb,
};
apollo-link-sentry
aims to be friendly with other apollo-link
packages, in the sense that we would like for you to be able to attach as much data as you want. For example, if you would like to add the HTTP headers you set with apollo-link-context
, you can do that by setting includeContextKeys: ['headers']
.
In case you find that there's a piece of data you're missing, feel free to open an issue.
Please note that Sentry sets some limits to how big events can be. For instance, events greater than 200KiB are immediately dropped (pre decompression). More information on that here. Be especially careful with the includeCache
option, as caches can become quite large.
Furthermore, much of the data you are sending to Sentry can include (sensitive) personal information. This might lead you to violating the terms of the GDPR. Use Sentry's beforeBreadrcrumb
function to filter out all sensitive data.
- I don't see any events appearing in my Sentry stream
- Note that this package (currently) only adds breadcrumbs. This means that you are still responsible for reporting errors to Sentry. You can do this by calling
Sentry.captureException()
. See this example:
<Mutation mutation={ERROR_MUTATION}> {(mutate, { data, error, loading }) => { if (loading) return <div>loading</div>; if (error) return <div>{error.toString()}</div>; const onClick = () => mutate().catch((error) => { Sentry.captureException(error); }); return <div> <button type="button" onClick={() => onClick()}>Mutate</button> {JSON.stringify(data)} </div> }} </Mutation>
- Note that this package (currently) only adds breadcrumbs. This means that you are still responsible for reporting errors to Sentry. You can do this by calling
- GraphQL operations are also logged as fetch breadcrumbs
- Sentry by default attaches all fetch events as breadcrumbs. This means that there are two ways to ensure GraphQL operations appear but once:
- Disable the default integration for fetch requests. Note that this is only recommended if you only use GraphQL requests in your application. The default integration can be disabled like this:
Sentry.init({ dsn: '', defaultIntegrations: [ new Sentry.Integrations.Breadcrumbs({ fetch: false }), ], });
- Otherwise, it will be possible to use the
beforeBreadcrumb
option of Sentry to filter out the duplicates. This feature is not yet implemented in this package, but it is on the roadmap (see below).
- Sentry by default attaches all fetch events as breadcrumbs. This means that there are two ways to ensure GraphQL operations appear but once:
- This package has not been tested for subscriptions
- We also need to test for different links, i.e.
apollo-link-rest
- Provide wrapper for Sentry's beforeBreadcrumb to filter out fetch requests
- Caveat: people using
unfetch
?
- Caveat: people using
- Write best practice scenario:
- setting
includeError
true - catch errors manually
- throw custom error
- how to use together with
apollo-link-error
?- does it report errors twice if you do sentry capture there and in your catch
- setting