Skip to content

Disable Awaitility uncaught-exception catching (fixes #11483)#11484

Open
ym0506 wants to merge 2 commits intotestcontainers:mainfrom
ym0506:codex/no-global-uncaught-handler
Open

Disable Awaitility uncaught-exception catching (fixes #11483)#11484
ym0506 wants to merge 2 commits intotestcontainers:mainfrom
ym0506:codex/no-global-uncaught-handler

Conversation

@ym0506
Copy link

@ym0506 ym0506 commented Feb 3, 2026

Fixes #11483

Testcontainers uses Awaitility in a few internal wait loops (e.g. during Docker client strategy probing, image pull retry, container start/port checks). Awaitility’s default behavior can temporarily install a global default uncaught exception handler, which may intercept uncaught exceptions from unrelated threads and can lead to surprising/flaky test behavior.

This change explicitly disables that behavior by adding .dontCatchUncaughtExceptions() to all internal Awaitility usages.

Tests:

  • Added a regression test to ensure the strategy probing code path includes dontCatchUncaughtExceptions, and to validate Awaitility does not intercept uncaught exceptions from other threads when configured accordingly.

@ym0506 ym0506 requested a review from a team as a code owner February 3, 2026 07:41
@ym0506
Copy link
Author

ym0506 commented Feb 3, 2026

CI workflows are awaiting maintainer approval (fork PR). Could a maintainer approve the workflows so required checks can run?

@ym0506
Copy link
Author

ym0506 commented Feb 10, 2026

Friendly ping @testcontainers/java-team — this PR is waiting on maintainer approval to run fork workflows.
Could someone approve workflows and take an initial look when possible? Thanks!

Comment on lines +19 to +32
@Test
void dockerClientProviderStrategyTestShouldUseDontCatchUncaughtExceptions() throws Exception {
byte[] bytes;
try (InputStream is = getClass()
.getClassLoader()
.getResourceAsStream("org/testcontainers/dockerclient/DockerClientProviderStrategy.class")) {
assertThat(is).isNotNull();
bytes = is.readAllBytes();
}

// Use ISO_8859_1 to preserve a stable 1:1 mapping of bytes to chars for a lightweight constant-pool substring check.
String content = new String(bytes, StandardCharsets.ISO_8859_1);
assertThat(content).contains("dontCatchUncaughtExceptions");
}
Copy link
Member

@rnorth rnorth Mar 6, 2026

Choose a reason for hiding this comment

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

I think this test is a bit unusual and fragile. I'm not sure if we should do this.

}

@Test
void shouldNotInterceptUncaughtExceptionsFromOtherThreads() throws Exception {
Copy link
Member

Choose a reason for hiding this comment

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

This is really testing Awaitility rather than Testcontainers. I understand the intention, but think that overall these tests might be overkill, and not pay off in the long run. I'd be inclined to not have them, but don't know how maintainers feel about it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Running testcontainers temporarily changes global uncaught exception handler

2 participants