@pbvision/fastify-firestore-service 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/api.md CHANGED
@@ -227,6 +227,9 @@ class DupErrorCodeAPI extends API {
227
227
  }
228
228
 
229
229
  async computeResponse (req) {
230
+ this.setSentryTag('test', 'me')
231
+ this.setSentryTag('another', 'test')
232
+ this.setSentryUserInfo({ email: 'x@example.com', id: '123' })
230
233
  if (req.body.exception === 'notfound') {
231
234
  throw new NotFoundException() // default error message "Not found"
232
235
  } else {
@@ -545,9 +548,9 @@ static CORS_ORIGIN = '*'
545
548
 
546
549
  ## Sentry Context
547
550
  By default, query parameter, path parameter and body parameters are included as
548
- context for reports to Sentry. To disable this, set
549
- `MAY_SHARE_INPUTS_WITH_SENTRY` to false. Note that headers are _not_ included
550
- by default. You can override what's included by overriding the `getInputsToTrackWithSentry()` method.
551
+ context for reports to Sentry. To disable or customize this, override the `getInputsToTrackWithSentry()` method. You can also use the
552
+ `setSentryContext()`, `setSentryTag()` and `setSentryUserInfo()` methods to
553
+ add custom metadata for the request.
551
554
 
552
555
 
553
556
  # Niche Concepts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pbvision/fastify-firestore-service",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "description": "Web Framework using Fastify and Firestore ORM",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/src/api/api.js CHANGED
@@ -2,7 +2,6 @@ import assert from 'node:assert'
2
2
  import querystring from 'node:querystring'
3
3
 
4
4
  import S from '@pbvision/schema'
5
- import * as Sentry from '@sentry/node'
6
5
 
7
6
  import fetchWrapper from '../fetch-wrapper.js'
8
7
 
@@ -215,6 +214,7 @@ class API {
215
214
  }
216
215
  reply.logRequestBodyOnError = this.constructor.LOG_REQUEST_BODY_ON_ERROR
217
216
  reply.apiName = this.constructor.name
217
+ this.req.__sentry = { context: {}, tags: {} }
218
218
  this.__trackInputsWithSentry()
219
219
  }
220
220
 
@@ -413,10 +413,10 @@ class API {
413
413
  * used if these fields don't include sensitive information.
414
414
  */
415
415
  __trackInputsWithSentry () {
416
- const inputs = this.getInputsToTrackWithSentry()
416
+ const inputs = this.constructor.getInputsToTrackWithSentry(this.req)
417
417
  // istanbul ignore else
418
418
  if (inputs) {
419
- Sentry.setContext('inputs', inputs)
419
+ this.setSentryContext('inputs', inputs)
420
420
  }
421
421
  }
422
422
 
@@ -427,14 +427,29 @@ class API {
427
427
  * helpful debugging information but should only be
428
428
  * used if these fields don't include sensitive information.
429
429
  */
430
- getInputsToTrackWithSentry () {
430
+ static getInputsToTrackWithSentry (req) {
431
431
  return {
432
- ...this.req.query,
433
- ...this.req.params,
434
- ...this.req.body
432
+ ...req.query,
433
+ ...req.params,
434
+ ...req.body
435
435
  }
436
436
  }
437
437
 
438
+ /** Sets context to be transmitted to Sentry if this request fails. */
439
+ setSentryContext (key, contextObject) {
440
+ this.req.__sentry.context[key] = contextObject
441
+ }
442
+
443
+ /** Sets a tag to be transmitted to Sentry if this request fails. */
444
+ setSentryTag (tag, tagValue) {
445
+ this.req.__sentry.tags[tag] = tagValue
446
+ }
447
+
448
+ /** Sets user info to be transmitted to Sentry if this request fails. */
449
+ setSentryUserInfo (userInfo) {
450
+ this.req.__sentry.userInfo = userInfo
451
+ }
452
+
438
453
  /**
439
454
  * Redirects to a URL optionally with query string and cookie.
440
455
  *
@@ -782,6 +797,16 @@ class API {
782
797
  let ret
783
798
  try {
784
799
  if (req.validationError) {
800
+ req.__sentry = { context: {} }
801
+ const errCopy = { ...req.validationError }
802
+ errCopy.validation = JSON.stringify(errCopy.validation, null, 4)
803
+ req.__sentry.context.validationError = errCopy
804
+ try {
805
+ req.__sentry.context.inputs = this.getInputsToTrackWithSentry(req)
806
+ } catch (err) {
807
+ // istanbul ignore next
808
+ console.warn('trying to get inputs to track failed', err)
809
+ }
785
810
  throw new InvalidInputException(req.validationError)
786
811
  }
787
812
  ret = await this._callAndHandleRequestDone(reply, async () => {
@@ -106,12 +106,20 @@ export default fp(function (fastify, options, next) {
106
106
  user.ip = req.ip
107
107
  }
108
108
  scope.setLevel(isCrash ? 'error' : 'warning')
109
- scope.setUser(user)
109
+ scope.setUser({
110
+ ...user,
111
+ ...(req.__sentry?.userInfo ?? {})
112
+ })
110
113
  scope.setTags({
114
+ ...(req.__sentry?.tags ?? {}),
111
115
  method: req.method,
112
116
  url: req.url,
113
117
  status: errInfo.status
114
118
  })
119
+ const customContexts = req.__sentry?.context ?? {}
120
+ for (const [k, v] of Object.entries(customContexts)) {
121
+ scope.setContext(k, v)
122
+ }
115
123
  const extras = {
116
124
  msg: errInfo.message,
117
125
  reqId: req.id,