Skip to content

Commit

Permalink
perf: Add withScope option
Browse files Browse the repository at this point in the history
BREAKING CHANGES: Removed `dsn` configuration option.
Added `withScope` option to configuration.

Thanks, @koenpunt for creating this brilliant changes to the library.
  • Loading branch information
maticzav authored Dec 7, 2018
2 parents 83b71de + b2862f8 commit 9919309
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 54 deletions.
47 changes: 26 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,19 @@ const resolvers = {
}

const sentryMiddleware = sentry({
dsn: process.env.SENTRY_DSN,
config: {
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
release: process.env.npm_package_version
},
extras: [
{ name:'body', path: 'request.body'},
{ name:'origin', path: 'request.headers.origin'},
{ name:'user-agent', path: "request.headers['user-agent']"}
]
withScope: (scope, error, context) => {
scope.setUser({
id: context.authorization.userId,
});
scope.setExtra('body', context.request.body)
scope.setExtra('origin', ctx.request.headers.origin)
scope.setExtra('user-agent', context.request.headers['user-agent'])
},
})

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

```ts
export interface Options {
dsn: string
config?: Sentry.NodeOptions
extras?: Extra[]
export interface Options<Context> {
config: Sentry.NodeOptions
withScope?: ExceptionScope<Context>
captureReturnedErrors?: boolean
forwardErrors?: boolean
}

function sentry(options: Options): IMiddlewareFunction
function sentry<Context>(options: Options<Context>): IMiddlewareFunction
```

### Extra Content
### Sentry context

To enrich events sent to Sentry, you can modify the [context](https://docs.sentry.io/enriching-error-data/context/?platform=javascript).
This can be done using the `withScope` configuration option.

The `withScope` option is a function that is called with the current Sentry scope, the error, and the GraphQL Context.

```ts
interface Extra {
name: string
path: string // path from ctx
}
type ExceptionScope<Context> = (
scope: Sentry.Scope,
error: any,
context: Context,
) => void
```

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.

### Options

| property | required | description |
| ----------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dsn` | true | Your [Sentry DSN](https://docs.sentry.io/error-reporting/quickstart/?platform=node#configure-the-sdk) |
| `config` | false | [Sentry's config object](https://docs.sentry.io/error-reporting/configuration/?platform=node) |
| `extras` | false | [Extra content](https://docs.sentry.io/enriching-error-data/context/?platform=node#extra-context) to send with the captured error. |
| `config` | true | [Sentry's config object](https://docs.sentry.io/error-reporting/configuration/?platform=node) |
| `withScope` | false | Function to modify the [Sentry context](https://docs.sentry.io/enriching-error-data/context/?platform=node) to send with the captured error. |
| `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 |
| `forwardErrors` | false | Should middleware forward errors to the client or block them. |

Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
},
"author": "Matic Zavadlal <matic.zavadlal@gmail.com>",
"dependencies": {
"@sentry/node": "^4.3.2",
"lodash": "^4.17.11"
"@sentry/node": "^4.3.2"
},
"devDependencies": {
"@types/lodash": "4.14.119",
Expand Down
48 changes: 22 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,47 @@
import * as Sentry from '@sentry/node'
import * as _ from 'lodash'

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

export interface Extra {
name: string
path: string
}
export type ExceptionScope<Context> = (
scope: Sentry.Scope,
error: any,
context: Context,
) => void

// Options for graphql-middleware-sentry
export interface Options {
dsn: string
config?: Sentry.NodeOptions
extras?: Extra[]
export interface Options<Context> {
config: Sentry.NodeOptions
withScope?: ExceptionScope<Context>
captureReturnedErrors?: boolean
forwardErrors?: boolean
}

export class SentryError extends Error {
constructor(...props) {
super(...props)
}
}
export class SentryError extends Error {}

export const sentry = ({
dsn,
export const sentry = <Context>({
config = {},
extras = [],
withScope,
captureReturnedErrors = false,
forwardErrors = false,
}: Options): IMiddlewareFunction => {
}: Options<Context>): IMiddlewareFunction => {
// Check if Sentry DSN is present
if (!dsn) {
if (!config.dsn) {
throw new SentryError(`Missing dsn parameter in configuration.`)
}

// Init Sentry
Sentry.init({ dsn, ...config })
Sentry.init(config)

// Return middleware resolver
return async function(resolve, parent, args, ctx, info) {
try {
const res = await resolve(parent, args, ctx, info)
if (captureReturnedErrors && res instanceof Error) {
captureException(res, ctx, extras)
captureException(res, ctx, withScope)
}
return res
} catch (err) {
captureException(err, ctx, extras)
captureException(err, ctx, withScope)

// Forward error
if (forwardErrors) {
Expand All @@ -57,11 +51,13 @@ export const sentry = ({
}
}

function captureException(err, ctx, extras: Extra[]) {
function captureException<Context>(
err,
ctx: Context,
withScope: ExceptionScope<Context>,
) {
Sentry.withScope(scope => {
extras.forEach(extra => {
scope.setExtra(extra.name, _.get(ctx, extra.path))
})
withScope(scope, err, ctx)
Sentry.captureException(err)
})
}
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1602,11 +1602,6 @@ lodash.toarray@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=

lodash@^4.17.11:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==

lodash@^4.17.4, lodash@^4.2.1:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
Expand Down

0 comments on commit 9919309

Please sign in to comment.