sentry-javascript: Exception on captureException() call

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which package are you using?

@sentry/node

SDK Version

7.11.1

Framework Version

No response

Link to Sentry event

No response

Steps to Reproduce

Catch exception, call captureException.

Expected Result

Exception being reported to Sentry

Actual Result

/home/node/node_modules/@sentry/utils/cjs/misc.js:25
    crypto && crypto.getRandomValues ? () => crypto.getRandomValues(new Uint8Array(1))[0] : () => Math.random() * 16;
                                                                                      ^

TypeError: Cannot read properties of undefined (reading '0')
    at /home/node/node_modules/@sentry/utils/cjs/misc.js:25:87
    at /home/node/node_modules/@sentry/utils/cjs/misc.js:30:19
    at String.replace (<anonymous>)
    at Object.uuid4 (/home/node/node_modules/@sentry/utils/cjs/misc.js:29:46)
    at Hub.captureException (/home/node/node_modules/@sentry/hub/cjs/hub.js:130:86)
    at /home/node/node_modules/@sentry/node/cjs/integrations/onuncaughtexception.js:71:17
    at Hub.withScope (/home/node/node_modules/@sentry/hub/cjs/hub.js:98:7)
    at OnUncaughtException.handler (/home/node/node_modules/@sentry/node/cjs/integrations/onuncaughtexception.js:69:15)
    at process.emit (node:events:525:35)
    at process.emit (node:domain:489:12)
    at process._fatalException (node:internal/process/execution:167:25)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 22 (8 by maintainers)

Most upvoted comments

I found the issue. We had a bad polyfill included by a dependency.

The polyfill was:

globalThis.crypto = {                                                                                                                                                                                                                                                                                                                                                                                        
  getRandomValues: function getRandomValues(b) {                                                                                                                                                                  
    require('crypto').randomFillSync(b) // missing return statement!                                                                                                                                                   
  },                                                                                                                                                                                                              
}

should have been:

globalThis.crypto = {                                                                                                                                                                                                                                                                                                                                                                                        
  getRandomValues: function getRandomValues(b) {                                                                                                                                                                  
    return require('crypto').randomFillSync(b)                                                                                                                                                                    
  },                                                                                                                                                                                                              
} 

I’m getting this same error, but for exception while calling captureException.

TypeError: Cannot read properties of undefined (reading 'exception')
  File "/node_modules/.pnpm/@sentry+node@6.19.7/node_modules/@sentry/src/integrations/linkederrors.ts", line 59, in e._handler
  File "/node_modules/.pnpm/@sentry+node@7.12.1/node_modules/@sentry/src/integrations/linkederrors.ts", line 10, in <anonymous>
  File "/node_modules/.pnpm/@sentry+hub@7.12.1/node_modules/@sentry/src/scope.ts", line 515, in <anonymous>
  File "/node_modules/.pnpm/@sentry+utils@7.12.1/node_modules/@sentry/src/syncpromise.ts", line 58, in new is
  File "/node_modules/.pnpm/@sentry+hub@7.12.1/node_modules/@sentry/src/scope.ts", line 510, in BA._notifyEventProcessors
...
(4 additional frame(s) were not displayed)

How is the error handling within the sentry node package so extremely poor, that errors like this bubble up with vague messaging instead of being caught within the lib, with proper custom errors (with codes) thrown? This is basic package authoring stuff folks.

There is some funky stuff going on in the kafkajs package: https://github.com/tulios/kafkajs/blob/master/src/producer/partitioners/legacy/randomBytes.js

I can’t pinpoint the exact problem yet but I bet it has to do with this.

Hi, @mark-b-ab.

Thanks for doing that investigation! The results are puzzling, though:

  • The global crypto object should only exist when running your node process with the --experimental-global-webcrypto flag. Are you? If not, I would not expect global.crypto to be defined at all, and yet for you it shows as { getRandomValues: [Function: getRandomValues] }.

  • Given that global.crypto is there at all, though, I’d expect it to have randomUUID (added in node 16), since you say you’re running your app in node 18.

  • global.crypto does seem to have getRandomValues (as I would expect, since it was added in node 15), but for some reason it’s returning undefined, which isn’t listed in the docs as one of the possible return values.

  • At the beginning of your test code, you call crypto.randomUUID and it’s undefined. At the end, you call randomUUID (which you say is from crypto) and it’s defined. I assume that’s because in the latter case you’re talking about actually having required/imported the built-in crypto module, rather than relying on the global version?

UPDATE: I did some experimenting on my own machine, with more confusing results. Specifically, while the node docs say that global.crypto should be different from the built-in crypto module, for me, both bare crypto and global.crypto give me the full crypto module, same as when I require('crypto'). (And no, I’m not running with the special flag I mentioned.) This happens in both node 14 and node 18.

In any case, my best guess is that maybe this has to do with the node binary you’re using inside your container. Do you know anything about it other than its version?

Meanwhile, @timfish, since you worked on this - do you have any idea what’s going on here? It all seems very strange…