getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.98k stars 1.57k forks source link

"Hook" is not exported by "node_modules/require-in-the-middle/index.js" #13851

Closed enuuros closed 1 month ago

enuuros commented 1 month ago

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/node

SDK Version

8.32.0

Framework Version

@sentry/node 8.32.0

Link to Sentry event

No response

Reproduction Example/SDK Setup

https://github.com/enuuros/sentry-esm-bug/tree/main

Steps to Reproduce

I'm trying to use @sentry/node in a backend service that is written in TypeScript. We use rollup to bundle all our code. Trying to bundle the example code Sentry provides here https://docs.sentry.io/platforms/javascript/guides/node/install/esm/ fails.

Steps to reproduce:

  1. git clone https://github.com/enuuros/sentry-esm-bug/tree/main
  2. npm install
  3. npm run bundle

Expected Result

The code should be bundled to dist/instrument.mjs

Actual Result



> sentry-esm-bug@1.0.0 bundle
> rollup -c rollup.config.js

src/instrument.ts → dist/instrument.js...
(!) "this" has been rewritten to "undefined"
https://rollupjs.org/troubleshooting/#error-this-is-undefined
node_modules/@opentelemetry/instrumentation-express/build/src/index.js
15:  * limitations under the License.
16:  */
17: var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
                           ^
18:     if (k2 === undefined) k2 = k;
19:     Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
...and 3 other occurrences
node_modules/@opentelemetry/instrumentation-fs/build/src/index.js
15:  * limitations under the License.
16:  */
17: var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
                           ^
18:     if (k2 === undefined) k2 = k;
19:     Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
...and 3 other occurrences
node_modules/@opentelemetry/instrumentation-undici/build/src/index.js
15:  * limitations under the License.
16:  */
17: var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
                           ^
18:     if (k2 === undefined) k2 = k;
19:     Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
...and 3 other occurrences

...and 45 other files
(!) Missing exports
https://rollupjs.org/troubleshooting/#error-name-is-not-exported-by-module
node_modules/@opentelemetry/instrumentation/build/esm/instrumentation.js
wrap is not exported by node_modules/shimmer/index.js
37:         this._config = {};
38:         /* Api to wrap instrumented method */
39:         this._wrap = shimmer.wrap;
                                 ^
40:         /* Api to unwrap instrumented methods */
41:         this._unwrap = shimmer.unwrap;
node_modules/@opentelemetry/instrumentation/build/esm/instrumentation.js
unwrap is not exported by node_modules/shimmer/index.js
39:         this._wrap = shimmer.wrap;
40:         /* Api to unwrap instrumented methods */
41:         this._unwrap = shimmer.unwrap;
                                   ^
42:         /* Api to mass wrap instrumented method */
43:         this._massWrap = shimmer.massWrap;
node_modules/@opentelemetry/instrumentation/build/esm/instrumentation.js
massWrap is not exported by node_modules/shimmer/index.js
41:         this._unwrap = shimmer.unwrap;
42:         /* Api to mass wrap instrumented method */
43:         this._massWrap = shimmer.massWrap;
                                     ^
44:         /* Api to mass unwrap instrumented methods */
45:         this._massUnwrap = shimmer.massUnwrap;
node_modules/@opentelemetry/instrumentation/build/esm/instrumentation.js
massUnwrap is not exported by node_modules/shimmer/index.js
43:         this._massWrap = shimmer.massWrap;
44:         /* Api to mass unwrap instrumented methods */
45:         this._massUnwrap = shimmer.massUnwrap;
                                       ^
46:         this.setConfig(config);
47:         this._diag = diag.createComponentLogger({
(!) Circular dependency
node_modules/@opentelemetry/sdk-trace-base/build/esm/index.js -> node_modules/@opentelemetry/sdk-trace-base/build/esm/BasicTracerProvider.js -> node_modules/@opentelemetry/sdk-trace-base/build/esm/index.js
[!] RollupError: node_modules/@opentelemetry/instrumentation/build/esm/platform/node/RequireInTheMiddleSingleton.js (27:9): "Hook" is not exported by "node_modules/require-in-the-middle/index.js", imported by "node_modules/@opentelemetry/instrumentation/build/esm/platform/node/RequireInTheMiddleSingleton.js".
https://rollupjs.org/troubleshooting/#error-name-is-not-exported-by-module
node_modules/@opentelemetry/instrumentation/build/esm/platform/node/RequireInTheMiddleSingleton.js (27:9)
25:     throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
26: };
27: import { Hook } from 'require-in-the-middle';
             ^
...
s1gr1d commented 1 month ago

Hello, this is a dependency from OpenTelemetry and apparently installing commonjs and json helps here (issue not quite related but maybe gives some information: https://github.com/open-telemetry/opentelemetry-js/issues/4191).

Can you try adding those plugins and see if that works for you?

import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";

plugins: [/* other plugins*/ commonjs(), json()]
enuuros commented 1 month ago

Adding those two plugins (the order is important) does resolve the bundling issue. However, it then fails at runtime:

$ node dist\instrument.mjs
Sentry Logger [warn]: Failed to register ESM hook Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'import-in-the-middle' imported from ...\dist\instrument.mjs
    at packageResolve (node:internal/modules/esm/resolve:854:9)
    at moduleResolve (node:internal/modules/esm/resolve:927:18)
    at defaultResolve (node:internal/modules/esm/resolve:1169:11)
    at nextResolve (node:internal/modules/esm/hooks:866:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:304:30)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:502:35)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:239:38)
    at ModuleLoader.import (node:internal/modules/esm/loader:472:34)
    at Hooks.register (node:internal/modules/esm/hooks:165:53)
    at MessagePort.handleMessage (node:internal/modules/esm/worker:196:24) {
  code: 'ERR_MODULE_NOT_FOUND'
}
s1gr1d commented 1 month ago

I was not able to reproduce this runtime error in the example repository. Could please update your code there so I can take another look? Thanks :)

enuuros commented 1 month ago

I think this was my mistake. I may have run it with a too old version of node.js (20.5.0) I got it working now with node 22.5.1. I updated the example repo anyway.

Thank your for your help! It was just a case of adding the proper rollup plugins.

Another thing I noticed is that the default PostgreSQL integration will not work if we use rollup to bundle pg with out own code (Sentry will not log any debug messages related to pg.query spans and we don't get anything in the sentry.io UI). If we keep pg as an external dependency (i.e. not bundle it), the default integration works.

I don't recall seeing any documentation about limitations related to bundling with @sentry/node, so I'm not sure if it should work or not.

Anyway, that is a separate issue and this issue can be closed.