Skip to content

feat(node-http-handler): passes client logger to request handler in codegen#2031

Draft
siddsriv wants to merge 2 commits into
smithy-lang:mainfrom
siddsriv:fix/client-logger-req-handler
Draft

feat(node-http-handler): passes client logger to request handler in codegen#2031
siddsriv wants to merge 2 commits into
smithy-lang:mainfrom
siddsriv:fix/client-logger-req-handler

Conversation

@siddsriv

@siddsriv siddsriv commented May 14, 2026

Copy link
Copy Markdown
Contributor

Issue #, if available:
aws/aws-sdk-js-v3#6130

Description of changes:
NodeHttpHandler emits socket exhaustion and request timeout warnings via console.warn, even when the user sets a custom logger on the SDK client. The client's logger and the request handler are assembled independently during client construction.

  • NodeHttpHandler.create() and the constructor now accept an optional clientLogger parameter. This is used as a fallback, if the user didn't explicitly set logger in the handler's own options, the client logger is used instead.
  • The generated runtimeConfig.ts now passes clientSharedValues.logger as an argument to RequestHandler.create()
  • Precedence: handler-level logger > client-level logger > console (fallback)

Testing

  • new unit tests
RUN  v3.2.4 /../smithy-typescript
  
   ✓ packages/node-http-handler/src/node-http-handler.spec.ts (38 tests)
  61ms
  
   Test Files  1 passed (1)
        Tests  38 passed (38)

Usage
Before (warning goes to console.warn):

  const client = new S3Client({
    logger: myLogger,
  });
  // Socket exhaustion warning still prints to console.warn

After (warning goes to myLogger.warn):

  const client = new S3Client({
    logger: myLogger,
  });
  // Socket exhaustion warning now routed through myLogger.warn

Output:

Output:
  
  [myLogger.warn] @smithy/node-http-handler:WARN - socket usage at
  capacity=50 and 100 additional requests are enqueued.

If one or more of the packages in the /packages directory has been modified, be sure yarn changeset add has been run and its output has
been committed and included in this pull request. See CONTRIBUTING.md.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

return new hsAgent({ keepAlive, maxSockets, ...httpsAgent });
})(),
logger,
logger: logger ?? clientLogger,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Handler-level logger (from NodeHttpHandlerOptions) takes precedence over the client-level logger.

) {
if (typeof (instanceOrOptions as any)?.handle === "function") {
// is already an instance of HttpHandler.
return instanceOrOptions as HttpHandler<any>;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When the user passes a pre-constructed handler instance (e.g. requestHandler: new NodeHttpHandler({...})), the client logger is not forwarded. The create() method returns the instance as-is. This is intentional, if you manually construct the handler, you own its configuration. Users who want the client logger in this case should pass logger explicitly in their NodeHttpHandler options.

@siddsriv siddsriv marked this pull request as ready for review May 14, 2026 20:01
@siddsriv siddsriv requested a review from a team as a code owner May 14, 2026 20:01
public static create(
instanceOrOptions?: HttpHandler<any> | NodeHttpHandlerOptions | Provider<NodeHttpHandlerOptions | void>
instanceOrOptions?: HttpHandler<any> | NodeHttpHandlerOptions | Provider<NodeHttpHandlerOptions | void>,
logger?: Logger

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why isn't this in the options arg?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

instanceOrOptions can be a Provider function, not just an object, so we can't inject into that i believe. A separate param would be cleaner(?), the handler resolves precedence internally as options.logger ?? clientLogger.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

discussed elsewhere -

I don't want to have a separate arg just for the client logger. We have several request handlers and they should all receive loggers through their primary constructor argument object.

It could perhaps be done in one of the config resolvers, which at their point have reference to the partially initialized config containing both the request handler and a client-level logger.

If the request handler has an async-init config, it would look like this:

function resolveSomeConfig(previouslyResolved) {
  if (previouslyResolved.requestHandler.configProvider is a promise) {
    configProvider = configProvider.then(c => {
      c.logger ??= previouslyResolved.logger || new LogLevel("warn");
    })
  }
}

@siddsriv siddsriv marked this pull request as draft May 14, 2026 20:33
@siddsriv

Copy link
Copy Markdown
Contributor Author

Converting to draft to discuss some design details for this one.

@siddsriv siddsriv changed the title feat(node-http-handler): passses client logger to request handler in codegen feat(node-http-handler): passes client logger to request handler in codegen May 15, 2026
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