Skip to content

Commit 9919309

Browse files
authored
perf: Add withScope option
BREAKING CHANGES: Removed `dsn` configuration option. Added `withScope` option to configuration. Thanks, @koenpunt for creating this brilliant changes to the library.
2 parents 83b71de + b2862f8 commit 9919309

File tree

4 files changed

+49
-54
lines changed

4 files changed

+49
-54
lines changed

README.md

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,19 @@ const resolvers = {
3030
}
3131

3232
const sentryMiddleware = sentry({
33-
dsn: process.env.SENTRY_DSN,
3433
config: {
34+
dsn: process.env.SENTRY_DSN,
3535
environment: process.env.NODE_ENV,
3636
release: process.env.npm_package_version
3737
},
38-
extras: [
39-
{ name:'body', path: 'request.body'},
40-
{ name:'origin', path: 'request.headers.origin'},
41-
{ name:'user-agent', path: "request.headers['user-agent']"}
42-
]
38+
withScope: (scope, error, context) => {
39+
scope.setUser({
40+
id: context.authorization.userId,
41+
});
42+
scope.setExtra('body', context.request.body)
43+
scope.setExtra('origin', ctx.request.headers.origin)
44+
scope.setExtra('user-agent', context.request.headers['user-agent'])
45+
},
4346
})
4447

4548
const server = GraphQLServer({
@@ -54,35 +57,37 @@ serve.start(() => `Server running on http://localhost:4000`)
5457
## API & Configuration
5558

5659
```ts
57-
export interface Options {
58-
dsn: string
59-
config?: Sentry.NodeOptions
60-
extras?: Extra[]
60+
export interface Options<Context> {
61+
config: Sentry.NodeOptions
62+
withScope?: ExceptionScope<Context>
6163
captureReturnedErrors?: boolean
6264
forwardErrors?: boolean
6365
}
6466

65-
function sentry(options: Options): IMiddlewareFunction
67+
function sentry<Context>(options: Options<Context>): IMiddlewareFunction
6668
```
6769

68-
### Extra Content
70+
### Sentry context
71+
72+
To enrich events sent to Sentry, you can modify the [context](https://docs.sentry.io/enriching-error-data/context/?platform=javascript).
73+
This can be done using the `withScope` configuration option.
74+
75+
The `withScope` option is a function that is called with the current Sentry scope, the error, and the GraphQL Context.
6976

7077
```ts
71-
interface Extra {
72-
name: string
73-
path: string // path from ctx
74-
}
78+
type ExceptionScope<Context> = (
79+
scope: Sentry.Scope,
80+
error: any,
81+
context: Context,
82+
) => void
7583
```
7684

77-
The `path` is used to get a value from the context object. It uses [lodash.get](https://lodash.com/docs/4.17.11#get) and it should follow its rules.
78-
7985
### Options
8086

8187
| property | required | description |
8288
| ----------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83-
| `dsn` | true | Your [Sentry DSN](https://docs.sentry.io/error-reporting/quickstart/?platform=node#configure-the-sdk) |
84-
| `config` | false | [Sentry's config object](https://docs.sentry.io/error-reporting/configuration/?platform=node) |
85-
| `extras` | false | [Extra content](https://docs.sentry.io/enriching-error-data/context/?platform=node#extra-context) to send with the captured error. |
89+
| `config` | true | [Sentry's config object](https://docs.sentry.io/error-reporting/configuration/?platform=node) |
90+
| `withScope` | false | Function to modify the [Sentry context](https://docs.sentry.io/enriching-error-data/context/?platform=node) to send with the captured error. |
8691
| `captureReturnedErrors` | false | Capture errors returned from other middlewares, e.g., `graphql-shield` [returns errors](https://github.com/maticzav/graphql-shield#custom-errors) from rules and resolvers |
8792
| `forwardErrors` | false | Should middleware forward errors to the client or block them. |
8893

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
},
2020
"author": "Matic Zavadlal <matic.zavadlal@gmail.com>",
2121
"dependencies": {
22-
"@sentry/node": "^4.3.2",
23-
"lodash": "^4.17.11"
22+
"@sentry/node": "^4.3.2"
2423
},
2524
"devDependencies": {
2625
"@types/lodash": "4.14.119",

src/index.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,47 @@
11
import * as Sentry from '@sentry/node'
2-
import * as _ from 'lodash'
32

43
import { IMiddlewareFunction } from 'graphql-middleware/dist/types'
54

6-
export interface Extra {
7-
name: string
8-
path: string
9-
}
5+
export type ExceptionScope<Context> = (
6+
scope: Sentry.Scope,
7+
error: any,
8+
context: Context,
9+
) => void
1010

1111
// Options for graphql-middleware-sentry
12-
export interface Options {
13-
dsn: string
14-
config?: Sentry.NodeOptions
15-
extras?: Extra[]
12+
export interface Options<Context> {
13+
config: Sentry.NodeOptions
14+
withScope?: ExceptionScope<Context>
1615
captureReturnedErrors?: boolean
1716
forwardErrors?: boolean
1817
}
1918

20-
export class SentryError extends Error {
21-
constructor(...props) {
22-
super(...props)
23-
}
24-
}
19+
export class SentryError extends Error {}
2520

26-
export const sentry = ({
27-
dsn,
21+
export const sentry = <Context>({
2822
config = {},
29-
extras = [],
23+
withScope,
3024
captureReturnedErrors = false,
3125
forwardErrors = false,
32-
}: Options): IMiddlewareFunction => {
26+
}: Options<Context>): IMiddlewareFunction => {
3327
// Check if Sentry DSN is present
34-
if (!dsn) {
28+
if (!config.dsn) {
3529
throw new SentryError(`Missing dsn parameter in configuration.`)
3630
}
3731

3832
// Init Sentry
39-
Sentry.init({ dsn, ...config })
33+
Sentry.init(config)
4034

4135
// Return middleware resolver
4236
return async function(resolve, parent, args, ctx, info) {
4337
try {
4438
const res = await resolve(parent, args, ctx, info)
4539
if (captureReturnedErrors && res instanceof Error) {
46-
captureException(res, ctx, extras)
40+
captureException(res, ctx, withScope)
4741
}
4842
return res
4943
} catch (err) {
50-
captureException(err, ctx, extras)
44+
captureException(err, ctx, withScope)
5145

5246
// Forward error
5347
if (forwardErrors) {
@@ -57,11 +51,13 @@ export const sentry = ({
5751
}
5852
}
5953

60-
function captureException(err, ctx, extras: Extra[]) {
54+
function captureException<Context>(
55+
err,
56+
ctx: Context,
57+
withScope: ExceptionScope<Context>,
58+
) {
6159
Sentry.withScope(scope => {
62-
extras.forEach(extra => {
63-
scope.setExtra(extra.name, _.get(ctx, extra.path))
64-
})
60+
withScope(scope, err, ctx)
6561
Sentry.captureException(err)
6662
})
6763
}

yarn.lock

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,11 +1602,6 @@ lodash.toarray@^4.4.0:
16021602
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
16031603
integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=
16041604

1605-
lodash@^4.17.11:
1606-
version "4.17.11"
1607-
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
1608-
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
1609-
16101605
lodash@^4.17.4, lodash@^4.2.1:
16111606
version "4.17.10"
16121607
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"

0 commit comments

Comments
 (0)