Uh oh!
There was an error while loading. Please reload this page.
feat: Autoload Database Integrations in Node environment - #3483
Conversation
147a445 to
6035456Comparesize-limit report
|
HazAT
commented
May 5, 2021
I am going to pick up the PR and carry it to the 🏁 |
e12e808 to
5561844CompareUh oh!
There was an error while loading. Please reload this page.
rhcarvalho
left a comment
There was a problem hiding this comment.
Is this going to work for all clients (the default one from init and custom clients)?
Can users disable those DB integrations the same way they can disable other integrations?
| try { | ||
| mod = dynamicRequire(module, moduleName); | ||
| } catch (e) { | ||
| // no-empty | ||
| } | ||
| try { | ||
| const { cwd } = dynamicRequire(module, 'process'); | ||
| mod = dynamicRequire(module, `${cwd()}/node_modules/${moduleName}`) as T; | ||
| } catch (e) { | ||
| // no-empty | ||
| } |
There was a problem hiding this comment.
Why does this try to assign mod twice? If the first dynamicRequire threw no exception, why don't we return mod there?
There was a problem hiding this comment.
Because T | undefined return type requires us to return on every branch anyway, so the best we could do is
try{mod=dynamicRequire(module,moduleName);}catch(e){// no-empty}try{const{ cwd }=dynamicRequire(module,'process');mod=dynamicRequire(module,`${cwd()}/node_modules/${moduleName}`)asT;}catch(e){// no-empty}returnundefined;In which case the current solution is imo more readable.
There was a problem hiding this comment.
Maybe I'm reading it wrong, but if there are no exceptions, this will execute linearly like this:
mod=dynamicRequire(module,moduleName);const{ cwd }=dynamicRequire(module,'process');mod=dynamicRequire(module,`${cwd()}/node_modules/${moduleName}`)asT;In which case mod = dynamicRequire(module, moduleName); is overwritten by mod = dynamicRequire(module, ${cwd()}/node_modules/${moduleName}) as T;.
I'd understand it better if it was
try{mod=dynamicRequire(module,moduleName);returnmod;// NEW CODE}catch(e){// no-empty}try{const{ cwd }=dynamicRequire(module,'process');mod=dynamicRequire(module,`${cwd()}/node_modules/${moduleName}`)asT;returnmod;// NEW CODE}catch(e){// no-empty}returnundefined;There was a problem hiding this comment.
We do want to override it, as if possible, we want the second value. This is to mimick 1:1 require.resolve behavior.
There was a problem hiding this comment.
Ah, I see. So why don't we start with what we want first, and fallback later?
The code as is is non-obvious.
| try{ | |
| mod=dynamicRequire(module,moduleName); | |
| }catch(e){ | |
| // no-empty | |
| } | |
| try{ | |
| const{ cwd }=dynamicRequire(module,'process'); | |
| mod=dynamicRequire(module,`${cwd()}/node_modules/${moduleName}`)asT; | |
| }catch(e){ | |
| // no-empty | |
| } | |
| try{ | |
| const{ cwd }=dynamicRequire(module,'process'); | |
| mod=dynamicRequire(module,`${cwd()}/node_modules/${moduleName}`)asT; | |
| returnmod | |
| }catch(e){ | |
| // ignore | |
| } | |
| try{ | |
| mod=dynamicRequire(module,moduleName); | |
| returnmod | |
| }catch(e){ | |
| // ignore | |
| } |
There was a problem hiding this comment.
This is to mimick 1:1
require.resolvebehavior.
Just saw this in the JSdoc; if we are trying to mimic also the side-effects of importing, then ignore my suggestion.
There was a problem hiding this comment.
It's stylistic thing already, and I don't want to run CI over and over again :P
There was a problem hiding this comment.
We’re changing in this same PR some unrelated code to return early, and here choose to do an import potentially twice :-)
The import is not only a style preference, it also contains potential side-effects. We are not profiling the code nor explicitly trying to make SDK startup as fast as possible, but we can also say that the double import also makes it overall slower.
No need to block on this, we've got 2 review approvals mine included!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
kamilogorek
commented
May 10, 2021
No, it won't work for custom clients, the same way as default integrations doesn't work for them.
Yes, with the same |
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Rodolfo Carvalho <rodolfo.carvalho@sentry.io>
x5a
commented
May 18, 2021
we're still investigating, but this change unexpectedly broke our apps in a very insidious and subtle way that caused a production outage - I'd encourage you to release this sort of monkey-patching-database-connectors change in a major version rather than a minor version. |
HazAT
commented
May 18, 2021
@x5a Can you provide a bit more info; How does your stack look like / how can we repro this? |
x5a
commented
May 19, 2021
@HazAT we're using postgres ( which maps to: https://github.com/getsentry/sentry-javascript/blob/master/packages/tracing/src/integrations/postgres.ts#L63 |
Kikobeats
commented
May 19, 2021
I opened a new issue to warn users the latest version is broken: |
elliotttf
commented
May 19, 2021
I can also confirm that this change has broken my application's postgres integration. In my case, the failure occurs when using a QueryStream via knex and pg-query-stream. The failure is due to the exact same reason that @x5a has pointed out. For example: conststream=knex('posts').select('*').stream();stream.pipe(someWritableStream);The resulting query object is a QueryStream and just like the cursor is not thenable. The assumption in the sentry code about the original query method being thenable fails but the error is swallowed in a not-obvious way. |
This feature will auto-load DB tracing integrations whenever a related package is available in the environment.
Postgres testing snippets: #3064
Mongo testing snippets: #3072
Mysql testing snippets: #3088
Docs: getsentry/sentry-docs#3563