Skip to content

fix(request): destroy request on timeout to prevent indefinite hang#173

Merged
mike-engel merged 1 commit intocustomerio:mainfrom
ehduardu:fix/request-timeout-handler
May 7, 2026
Merged

fix(request): destroy request on timeout to prevent indefinite hang#173
mike-engel merged 1 commit intocustomerio:mainfrom
ehduardu:fix/request-timeout-handler

Conversation

@ehduardu
Copy link
Copy Markdown
Contributor

@ehduardu ehduardu commented Apr 24, 2026

Problem

Setting the timeout option on TrackClient does not actually cause requests to fail after the timeout. https.request only emits a 'timeout' event on socket idleness — it doesn't destroy the request. Since request.ts never registers a 'timeout' listener, the event is ignored and the returned Promise hangs forever.
In practice this means that if Customer.io is slow to respond or a socket becomes half-dead, every caller that awaits the client will hang indefinitely. In our case this caused a RabbitMQ redelivery storm and duplicate email sends to end users.

Fix

Register a 'timeout' handler that destroys the request with a clear error. The existing 'error' handler then rejects the Promise normally.

Test

Added a test that points the client at a server which never responds and asserts the Promise rejects within the configured timeout.


Note

Medium Risk
Changes request lifecycle behavior by destroying the underlying https request on socket timeout, which can affect error handling and retry behavior for all callers. Scope is small and covered by a new unit test, but it impacts a core networking path.

Overview
Prevents CIORequest.handler calls from hanging indefinitely by adding a req.on('timeout') listener that destroys the request with a clear timeout error message.

Adds a focused test to assert the promise rejects when the request emits a socket timeout, ensuring the timeout option actually fails the request rather than leaving it pending.

Reviewed by Cursor Bugbot for commit b16178f. Bugbot is set up for automated code reviews on this repo. Configure here.

@ehduardu ehduardu changed the title fix: destroy request on timeout to prevent indefinite hang fix(request): destroy request on timeout to prevent indefinite hang Apr 24, 2026
@ehduardu
Copy link
Copy Markdown
Contributor Author

ehduardu commented May 5, 2026

@avigoldman @clabland @karngyan
Hey guys, what’s up? 👋

I pushed this change since I’ve been running into a timeout issue. Could you please take a look when you have some time?

Thanks!

@mike-engel mike-engel merged commit cec1414 into customerio:main May 7, 2026
8 checks passed
@mike-engel
Copy link
Copy Markdown
Collaborator

Thanks for your patience @ehduardu!

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