Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix socket info in fetch response #555

Merged
merged 3 commits into from
Dec 4, 2024
Merged

fix: fix socket info in fetch response #555

merged 3 commits into from
Dec 4, 2024

Conversation

killagu
Copy link
Member

@killagu killagu commented Dec 4, 2024

Summary by CodeRabbit

  • New Features

    • Introduced the BaseAgent class with enhanced asynchronous local storage capabilities.
    • Updated HttpAgent to extend BaseAgent, improving address validation and error handling during dispatch operations.
  • Bug Fixes

    • Enhanced validation in the dispatch method of HttpAgent to ensure hostname validity.
  • Tests

    • Added a new assertion in the fetch tests to verify the local address of the response socket.
  • Chores

    • Removed the fetchOpaqueInterceptor function and associated imports to streamline the codebase.

@killagu killagu requested a review from fengmk2 December 4, 2024 14:50
Copy link

coderabbitai bot commented Dec 4, 2024

Warning

Rate limit exceeded

@killagu has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 20 minutes and 27 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 457fa29 and b7a9e61.

Walkthrough

The changes introduce a new BaseAgent class that enhances the Agent class from the undici library by adding asynchronous local storage capabilities. The HttpAgent class is updated to extend BaseAgent, improving address validation and error handling. The fetchOpaqueInterceptor function is removed from the FetchOpaqueInterceptor file, simplifying the interceptor logic. Additionally, the FetchFactory class is modified to use the new dispatcher architecture, and tests are adjusted to validate response properties more thoroughly.

Changes

File Change Summary
src/BaseAgent.ts Added BaseAgent class and BaseAgentOptions interface; overridden dispatch method.
src/FetchOpaqueInterceptor.ts Removed fetchOpaqueInterceptor function and related comments; deleted unused import.
src/HttpAgent.ts Updated HttpAgent to extend BaseAgent; modified constructor and dispatch method for validation.
src/fetch.ts Changed dispatcher type to Dispatcher.ComposedDispatcher; updated setClientOptions method to use BaseAgentOptions.
test/fetch.test.ts Added assertion to verify localAddress in fetch response; no other changes made.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant FetchFactory
    participant BaseAgent
    participant HttpAgent

    Client->>FetchFactory: setClientOptions()
    FetchFactory->>BaseAgent: instantiate()
    BaseAgent->>HttpAgent: dispatch(options, handler)
    HttpAgent->>BaseAgent: validate address
    BaseAgent->>BaseAgent: retrieve opaque storage
    BaseAgent->>HttpAgent: call superclass dispatch
Loading

🐰 "In the code, a new class takes flight,
With storage so local, it's quite a sight.
The fetch now is swift, with checks all around,
Errors caught early, no more to be found.
So hop on this change, let’s celebrate cheer,
With agents and fetches, our path is now clear!" 🐇


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

pkg-pr-new bot commented Dec 4, 2024

Open in Stackblitz

npm i https://pkg.pr.new/node-modules/urllib@555

commit: b7a9e61

Copy link

pkg-pr-new bot commented Dec 4, 2024

Open in Stackblitz

npm i https://pkg.pr.new/node-modules/urllib@555

commit: 457fa29

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (2)
src/HttpAgent.ts (1)

Line range hint 35-54: Critical Issue: Ensure opaqueLocalStorage is passed to BaseAgent

In the HttpAgent constructor, when calling super(), the opaqueLocalStorage property from options might not be included in baseOpts. This can lead to this.#opaqueLocalStorage being undefined in BaseAgent, causing a TypeError when calling getStore() on undefined.

Apply the following diff to ensure opaqueLocalStorage is passed to the super() call:

constructor(options: HttpAgentOptions) {
  /* eslint node/prefer-promises/dns: off*/
  const { lookup = dns.lookup, ...baseOpts } = options;

  const lookupFunction: LookupFunction = (hostname, dnsOptions, callback) => {
    // existing code...
  };
  super({
    ...baseOpts,
+   opaqueLocalStorage: options.opaqueLocalStorage,
    connect: { ...options.connect, lookup: lookupFunction, allowH2: options.allowH2 },
  });
  this.#checkAddress = options.checkAddress;
}

This ensures that opaqueLocalStorage is properly passed to BaseAgent, preventing the TypeError.

src/fetch.ts (1)

Line range hint 61-107: Critical Issue: Preserve opaqueLocalStorage in dispatcherOption

When setting client options in FetchFactory, the dispatcherOption object might lose the opaqueLocalStorage property during reassignment. This can result in opaqueLocalStorage being undefined when constructing the dispatcher, leading to a TypeError in BaseAgent.

Ensure that opaqueLocalStorage is preserved in dispatcherOption during reassignment. Apply this diff:

static setClientOptions(clientOptions: ClientOptions) {
  let dispatcherOption: BaseAgentOptions = {
    opaqueLocalStorage: FetchFactory.#opaqueLocalStorage,
  };
  let dispatcherClazz: new (options: BaseAgentOptions) => BaseAgent = BaseAgent;
  if (clientOptions?.lookup || clientOptions?.checkAddress) {
    dispatcherOption = {
-     ...dispatcherOption,
+     opaqueLocalStorage: FetchFactory.#opaqueLocalStorage,
      lookup: clientOptions.lookup,
      checkAddress: clientOptions.checkAddress,
      connect: clientOptions.connect,
      allowH2: clientOptions.allowH2,
    } as HttpAgentOptions;
    dispatcherClazz = HttpAgent as unknown as new (options: BaseAgentOptions) => BaseAgent;
  } else if (clientOptions?.connect) {
    dispatcherOption = {
-     ...dispatcherOption,
+     opaqueLocalStorage: FetchFactory.#opaqueLocalStorage,
      connect: clientOptions.connect,
      allowH2: clientOptions.allowH2,
    } as HttpAgentOptions;
    dispatcherClazz = BaseAgent;
  } else if (clientOptions?.allowH2) {
    dispatcherOption = {
-     ...dispatcherOption,
+     opaqueLocalStorage: FetchFactory.#opaqueLocalStorage,
      allowH2: clientOptions.allowH2,
    } as HttpAgentOptions;
    dispatcherClazz = BaseAgent;
  }
  FetchFactory.#dispatcher = new dispatcherClazz(dispatcherOption);
  initDiagnosticsChannel();
}

This ensures opaqueLocalStorage remains part of dispatcherOption regardless of the client options provided.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 12c4e3c and fe689a4.

📒 Files selected for processing (5)
  • src/BaseAgent.ts (1 hunks)
  • src/FetchOpaqueInterceptor.ts (0 hunks)
  • src/HttpAgent.ts (2 hunks)
  • src/fetch.ts (5 hunks)
  • test/fetch.test.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/FetchOpaqueInterceptor.ts
🧰 Additional context used
🪛 GitHub Check: Node.js / Test (ubuntu-latest, 23)
src/BaseAgent.ts

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.234, keepAliveSocket: true, requestUrls: [ 'http://localhost:37319/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.114, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.139, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:37319/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.105, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:37319/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

test/fetch.test.ts

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

'::1' !== '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

🪛 GitHub Check: Node.js / Test (ubuntu-latest, 22)
src/BaseAgent.ts

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.251, keepAliveSocket: true, requestUrls: [ 'http://localhost:40029/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.099, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.077, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:40029/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.133, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:40029/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

test/fetch.test.ts

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • '::1'

  • '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

🪛 GitHub Check: Node.js / Test (ubuntu-latest, 20)
src/BaseAgent.ts

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.287, keepAliveSocket: true, requestUrls: [ 'http://localhost:46867/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.135, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.166, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:46867/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.133, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:46867/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

test/fetch.test.ts

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • '::1'

  • '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

🪛 GitHub Check: Node.js / Test (macos-latest, 22)
src/BaseAgent.ts

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.185, keepAliveSocket: true, requestUrls: [ 'http://localhost:49196/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.072, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.035, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:49196/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.053, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:49196/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

test/fetch.test.ts

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • '::1'

  • '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

src/BaseAgent.ts Outdated
Comment on lines 8 to 25
export interface BaseAgentOptions extends Agent.Options {
opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
}

export class BaseAgent extends Agent {
#opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;

constructor(options: BaseAgentOptions) {
super(options);
this.#opaqueLocalStorage = options.opaqueLocalStorage;
}

dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
const opaque = this.#opaqueLocalStorage.getStore();
(handler as any).opaque = opaque;
return super.dispatch(options, handler);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical Issue: Handle Undefined opaqueLocalStorage

If opaqueLocalStorage is not provided in options, accessing this.#opaqueLocalStorage.getStore() will result in a TypeError. To prevent this, you should provide a default value or handle the case where opaqueLocalStorage is undefined.

Apply this diff to provide a default value for opaqueLocalStorage:

export interface BaseAgentOptions extends Agent.Options {
- opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
+ opaqueLocalStorage?: AsyncLocalStorage<FetchOpaque>;
}

export class BaseAgent extends Agent {
  #opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;

  constructor(options: BaseAgentOptions) {
    super(options);
-   this.#opaqueLocalStorage = options.opaqueLocalStorage;
+   this.#opaqueLocalStorage = options.opaqueLocalStorage ?? new AsyncLocalStorage<FetchOpaque>();
  }

  dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
-   const opaque = this.#opaqueLocalStorage.getStore();
+   const opaque = this.#opaqueLocalStorage?.getStore();
    (handler as any).opaque = opaque;
    return super.dispatch(options, handler);
  }
}

This modification ensures that opaqueLocalStorage has a default value and gracefully handles cases where it's not provided.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface BaseAgentOptions extends Agent.Options {
opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
}
export class BaseAgent extends Agent {
#opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
constructor(options: BaseAgentOptions) {
super(options);
this.#opaqueLocalStorage = options.opaqueLocalStorage;
}
dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
const opaque = this.#opaqueLocalStorage.getStore();
(handler as any).opaque = opaque;
return super.dispatch(options, handler);
}
}
export interface BaseAgentOptions extends Agent.Options {
opaqueLocalStorage?: AsyncLocalStorage<FetchOpaque>;
}
export class BaseAgent extends Agent {
#opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
constructor(options: BaseAgentOptions) {
super(options);
this.#opaqueLocalStorage = options.opaqueLocalStorage ?? new AsyncLocalStorage<FetchOpaque>();
}
dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
const opaque = this.#opaqueLocalStorage?.getStore();
(handler as any).opaque = opaque;
return super.dispatch(options, handler);
}
}
🧰 Tools
🪛 GitHub Check: Node.js / Test (ubuntu-latest, 23)

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.234, keepAliveSocket: true, requestUrls: [ 'http://localhost:37319/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.114, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.139, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:37319/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.105, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:37319/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

🪛 GitHub Check: Node.js / Test (ubuntu-latest, 22)

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.251, keepAliveSocket: true, requestUrls: [ 'http://localhost:40029/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.099, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.077, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:40029/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.133, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:40029/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

🪛 GitHub Check: Node.js / Test (ubuntu-latest, 20)

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.287, keepAliveSocket: true, requestUrls: [ 'http://localhost:46867/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.135, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.166, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:46867/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.133, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:46867/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

🪛 GitHub Check: Node.js / Test (macos-latest, 22)

[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTP protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:255:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.185, keepAliveSocket: true, requestUrls: [ 'http://localhost:49196/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.lookup > should work with custom lookup on HTTPS protol
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:279:39

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.072, keepAliveSocket: true, requestUrls: [ 'https://registry.npmmirror.com/urllib' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should check ip hostname
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:382:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.035, keepAliveSocket: true, requestUrls: [ 'http://127.0.0.1:49196/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }


[failure] 21-21: test/HttpClient.test.ts > HttpClient.test.ts > clientOptions.checkAddress > should allow hostname check
TypeError: Cannot read properties of undefined (reading 'getStore')
❯ HttpAgent.dispatch src/BaseAgent.ts:21:45
❯ HttpAgent.dispatch src/HttpAgent.ts:90:18
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:188:10
❯ node_modules/undici/lib/api/api-request.js:179:15
❯ HttpAgent.request node_modules/undici/lib/api/api-request.js:178:12
❯ Proxy. node_modules/undici/index.js:109:15
❯ HttpClient.#requestInternal src/HttpClient.ts:581:28
❯ HttpClient.request src/HttpClient.ts:245:23
❯ test/HttpClient.test.ts:472:41

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { opaque: undefined, status: -1, headers: {}, res: { status: -1, statusCode: -1, statusText: '', statusMessage: '', headers: {}, size: +0, aborted: false, rt: 0.053, keepAliveSocket: true, requestUrls: [ 'http://check-host-ssrf.com:49196/' ], timing: { queuing: +0, connected: +0, requestHeadersSent: +0, requestSent: +0, waiting: +0, contentDownload: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 }, retries: +0, socketErrorRetries: +0 }, socket: { id: +0, localAddress: '', localPort: +0, remoteAddress: '', remotePort: +0, remoteFamily: '', bytesWritten: +0, bytesRead: +0, handledRequests: +0, handledResponses: +0 } }

@@ -46,6 +46,7 @@
assert(requestDiagnosticsMessage!.request);
assert(responseDiagnosticsMessage!.request);
assert(responseDiagnosticsMessage!.response);
assert.equal(responseDiagnosticsMessage!.response.socket.localAddress, '127.0.0.1');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix Test Assertion to Support IPv6 Loopback Address

The test is failing because the localAddress is '::1' (IPv6 loopback) instead of '127.0.0.1' (IPv4 loopback). This can happen in environments where IPv6 is preferred. To make the test more robust, adjust the assertion to accept both IPv4 and IPv6 loopback addresses.

Apply this diff to update the assertion:

assert.equal(responseDiagnosticsMessage!.response.socket.localAddress, '127.0.0.1');
+ assert(['127.0.0.1', '::1'].includes(responseDiagnosticsMessage!.response.socket.localAddress));

Alternatively, use a regular expression to match any loopback address:

+ assert(/^(127\.0\.0\.1|::1)$/.test(responseDiagnosticsMessage!.response.socket.localAddress));

This adjustment ensures the test passes regardless of whether the environment uses IPv4 or IPv6 for loopback addresses.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 GitHub Check: Node.js / Test (ubuntu-latest, 23)

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

'::1' !== '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

🪛 GitHub Check: Node.js / Test (ubuntu-latest, 22)

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • '::1'

  • '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

🪛 GitHub Check: Node.js / Test (ubuntu-latest, 20)

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • '::1'

  • '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

🪛 GitHub Check: Node.js / Test (macos-latest, 22)

[failure] 49-49: test/fetch.test.ts > fetch.test.ts > fetch should work
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • '::1'

  • '127.0.0.1'

Expected: "127.0.0.1"
Received: "::1"

❯ test/fetch.test.ts:49:12

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fe689a4 and 457fa29.

📒 Files selected for processing (1)
  • src/BaseAgent.ts (1 hunks)
🔇 Additional comments (4)
src/BaseAgent.ts (4)

1-7: LGTM: Imports are well-structured

The imports are properly organized, using correct module specifiers including the node: prefix for Node.js built-in modules.


12-14: LGTM: Class structure and field declaration

The class properly extends Agent and declares the private field with correct TypeScript syntax.


8-10: ⚠️ Potential issue

Consider making opaqueLocalStorage required

The optional opaqueLocalStorage is causing runtime errors in tests when getStore() is called on undefined storage. Consider making this field required to prevent runtime errors, or ensure proper null checks are implemented throughout the codebase.

Apply this diff to make the field required:

export interface BaseAgentOptions extends Agent.Options {
-  opaqueLocalStorage?: AsyncLocalStorage<FetchOpaque>;
+  opaqueLocalStorage: AsyncLocalStorage<FetchOpaque>;
}

Likely invalid or redundant comment.


15-26: Verify test coverage for error cases

The implementation needs verification against the failing test cases, particularly around undefined opaqueLocalStorage.

✅ Verification successful

Verify test coverage for undefined opaqueLocalStorage

The implementation correctly handles undefined opaqueLocalStorage through optional chaining (?.) in the dispatch method. The test coverage is comprehensive:

  • The options.opaque.test.ts file contains tests for both successful and error cases with opaque data
  • The HttpClient.events.test.ts verifies opaque data propagation through the request/response cycle
  • The diagnostics_channel.test.ts validates opaque data handling in diagnostic traces

The TypeError mentioned in the review comment is not reproducible as the code properly handles undefined cases through the optional chaining operator. No changes are needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check test coverage and usage patterns

# Find all test files that might be affected
echo "Checking test files that use BaseAgent:"
rg -l "BaseAgent" "test/"

# Check for proper initialization patterns
echo "Checking BaseAgent initialization patterns:"
rg -A 3 "new BaseAgent\(" "test/"

# Look for potential undefined opaqueLocalStorage usage
echo "Checking opaqueLocalStorage usage:"
rg "opaqueLocalStorage" "test/"

Length of output: 352


Script:

#!/bin/bash
# Let's try a broader search to understand the test coverage

# Find all test files in the repository
echo "All test files:"
fd "test" --type f

# Check for any test files containing Agent in their name or content
echo -e "\nFiles containing Agent:"
rg -l "Agent" --type ts

# Look for test setup or mock patterns
echo -e "\nTest setup patterns:"
rg -A 5 "describe|it\(" --type ts "test/"

# Check the actual BaseAgent implementation for better context
echo -e "\nBaseAgent implementation:"
cat src/BaseAgent.ts

Length of output: 74585


Script:

#!/bin/bash
# Let's check for test files specifically related to BaseAgent and opaque storage

# Find test files that might test BaseAgent functionality
echo "Looking for BaseAgent tests:"
rg -l "BaseAgent" "test/" --type ts

# Check for opaque storage related tests
echo -e "\nChecking opaque storage tests:"
rg -B 3 -A 3 "opaqueLocalStorage" "test/" --type ts

# Look at the BaseAgent implementation
echo -e "\nBaseAgent implementation:"
cat src/BaseAgent.ts

# Check for opaque related test cases
echo -e "\nOpaque test cases:"
rg -B 3 -A 3 "opaque" "test/" --type ts

Length of output: 17533

Comment on lines +20 to +26
dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
const opaque = this.#opaqueLocalStorage?.getStore();
if (opaque) {
(handler as any).opaque = opaque;
}
return super.dispatch(options, handler);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve type safety and error handling in dispatch

The current implementation has several areas for improvement:

  1. Using any type assertion is unsafe
  2. No error handling for dispatch failures
  3. Potential undefined access even with optional chaining

Consider this safer implementation:

  dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
-   const opaque = this.#opaqueLocalStorage?.getStore();
-   if (opaque) {
-     (handler as any).opaque = opaque;
-   }
-   return super.dispatch(options, handler);
+   try {
+     const opaque = this.#opaqueLocalStorage?.getStore();
+     if (opaque) {
+       // Use a type intersection instead of 'any'
+       (handler as Dispatcher.DispatchHandler & { opaque: FetchOpaque }).opaque = opaque;
+     }
+     return super.dispatch(options, handler);
+   } catch (error) {
+     // Log error or handle it appropriately
+     throw new Error(`Failed to dispatch request: ${error.message}`);
+   }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
const opaque = this.#opaqueLocalStorage?.getStore();
if (opaque) {
(handler as any).opaque = opaque;
}
return super.dispatch(options, handler);
}
dispatch(options: Agent.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean {
try {
const opaque = this.#opaqueLocalStorage?.getStore();
if (opaque) {
// Use a type intersection instead of 'any'
(handler as Dispatcher.DispatchHandler & { opaque: FetchOpaque }).opaque = opaque;
}
return super.dispatch(options, handler);
} catch (error) {
// Log error or handle it appropriately
throw new Error(`Failed to dispatch request: ${error.message}`);
}
}

@fengmk2 fengmk2 changed the title fix: fix socket info in response fix: fix socket info in fetch response Dec 4, 2024
@fengmk2 fengmk2 merged commit 629c7a3 into master Dec 4, 2024
22 checks passed
@fengmk2 fengmk2 deleted the fix/socketinfo branch December 4, 2024 15:03
fengmk2 pushed a commit that referenced this pull request Dec 4, 2024
[skip ci]

## [4.6.1](v4.6.0...v4.6.1) (2024-12-04)

### Bug Fixes

* fix socket info in response ([#555](#555)) ([629c7a3](629c7a3))
Copy link

codecov bot commented Dec 4, 2024

Codecov Report

Attention: Patch coverage is 86.95652% with 3 lines in your changes missing coverage. Please review.

Project coverage is 93.69%. Comparing base (3c9fca7) to head (b7a9e61).
Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
src/fetch.ts 57.14% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #555      +/-   ##
==========================================
+ Coverage   93.20%   93.69%   +0.48%     
==========================================
  Files          10       11       +1     
  Lines        1222     1221       -1     
  Branches      289      295       +6     
==========================================
+ Hits         1139     1144       +5     
+ Misses         79       73       -6     
  Partials        4        4              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants