Skip to content

Commit 959cf7e

Browse files
authored
test(node-integration): Retry RabbitMQ connect in amqplib scenario (#21062)
## Summary - Wraps `connectToRabbitMQ()` in `suites/tracing/amqplib/scenario.mjs` with a 5-attempt, 1-second-backoff retry loop. First attempt is unchanged; only retries trigger on connect rejection. ## Root cause From the [failing run](https://github.com/getsentry/sentry-javascript/actions/runs/26030287555/job/76514895508): ``` FAIL suites/tracing/amqplib/test.ts > amqplib auto-instrumentation > esm/cjs > esm > should be able to send and receive messages Error: Expected envelope item type 'transaction' but got 'event'. Item: [{"type":"event"},{"exception":{"values":[{"type":"Error","value":"Socket closed abruptly during opening handshake", ... ``` The docker-compose healthcheck (`rabbitmq-diagnostics -q ping`) reports the broker ready before its AMQP listener can complete the protocol handshake. So: 1. Healthcheck passes → runner launches the scenario. 2. `await amqp.connect(AMQP_URL)` rejects with `Socket closed abruptly during opening handshake`. 3. The rejection isn't caught by the top-level IIFE → `OnUnhandledRejection` integration captures it → Sentry sends it as an error envelope. 4. The runner's strict envelope-stream parser (`utils/runner.ts:509`) sees an `event` where it expected a `transaction` and throws. ## Fix Add a retry loop around `amqp.connect` + `createChannel`. The first attempt path is unchanged (no extra latency in the common case). On transient connection rejection, retry up to 4 more times with 1 s spacing — total worst-case extra time 4 s, well within the test's 60 s timeout. After 5 failures, throws `lastError` (same failure mode as today, just delayed). Connection retry is the industry-standard pattern for broker-readiness races where the healthcheck reports a coarser signal than the actual protocol. The change is purely additive — first-attempt success is unchanged, assertions are unchanged, and a truly broken broker still surfaces as a scenario failure. Fixes #20969 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 385caac commit 959cf7e

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

  • dev-packages/node-integration-tests/suites/tracing/amqplib

dev-packages/node-integration-tests/suites/tracing/amqplib/scenario.mjs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,26 @@ const QUEUE_OPTIONS = {
3535
})();
3636

3737
async function connectToRabbitMQ() {
38-
const connection = await amqp.connect(AMQP_URL);
39-
const channel = await connection.createChannel();
40-
return { connection, channel };
38+
// Retry up to 5 times with 1s backoff. The docker-compose healthcheck
39+
// (`rabbitmq-diagnostics -q ping`) reports the broker ready before AMQP
40+
// handshakes actually succeed, so the first connect can race with broker
41+
// boot and reject with "Socket closed abruptly during opening handshake".
42+
// That rejection becomes an unhandled rejection captured by Sentry and
43+
// sent as an error envelope, which the runner sees ahead of the expected
44+
// transaction and reports as "Expected envelope item type 'transaction'
45+
// but got 'event'" (the flake reported in the issue).
46+
let lastError;
47+
for (let attempt = 0; attempt < 5; attempt++) {
48+
try {
49+
const connection = await amqp.connect(AMQP_URL);
50+
const channel = await connection.createChannel();
51+
return { connection, channel };
52+
} catch (err) {
53+
lastError = err;
54+
await new Promise(resolve => setTimeout(resolve, 1000));
55+
}
56+
}
57+
throw lastError;
4158
}
4259

4360
async function createQueue(queueName, channel) {

0 commit comments

Comments
 (0)