CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-awaitility--awaitility

A Java DSL for synchronizing asynchronous operations

Pending
Overview
Eval results
Files

exception-handling.mddocs/

Exception Handling

Configurable exception ignoring strategies for handling expected failures during condition evaluation without causing test failures.

Capabilities

Basic Exception Ignoring

Control whether exceptions during condition evaluation cause immediate test failure or are treated as false condition results.

Ignore All Exceptions

/**
 * Ignore all exceptions during condition evaluation
 * Exceptions are treated as condition returning false
 * @return ConditionFactory for further configuration
 */
ConditionFactory ignoreExceptions();

Usage Example:

// Ignore all exceptions until service is ready
await().ignoreExceptions()
    .atMost(30, SECONDS)
    .until(() -> serviceClient.healthCheck().getStatus() == Status.OK);

Ignore No Exceptions

/**
 * Don't ignore any exceptions (default behavior)
 * Any exception during condition evaluation fails the test immediately
 * @return ConditionFactory for further configuration
 */
ConditionFactory ignoreNoExceptions();

Specific Exception Types

Ignore only specific exception types while allowing others to fail the test.

Single Exception Type

/**
 * Ignore specific exception type during condition evaluation
 * @param exceptionType class of exceptions to ignore
 * @return ConditionFactory for further configuration
 */
ConditionFactory ignoreException(Class<? extends Throwable> exceptionType);

/**
 * Alternative method name for ignoring specific exception instances
 * @param exceptionType class of exceptions to ignore
 * @return ConditionFactory for further configuration
 */
ConditionFactory ignoreExceptionsInstanceOf(Class<? extends Throwable> exceptionType);

Usage Examples:

// Ignore connection timeouts while waiting for service
await().ignoreException(ConnectTimeoutException.class)
    .atMost(2, MINUTES)
    .until(() -> httpClient.get("/health").getStatusCode() == 200);

// Ignore SQL exceptions during database initialization
await().ignoreExceptionsInstanceOf(SQLException.class)
    .until(() -> {
        try (Connection conn = dataSource.getConnection()) {
            return conn.isValid(1);
        }
    });

Predicate-Based Exception Filtering

Use predicates to define complex exception ignoring logic.

Predicate Matching

/**
 * Ignore exceptions matching the given predicate
 * @param predicate function that tests whether to ignore exception
 * @return ConditionFactory for further configuration
 */
ConditionFactory ignoreExceptionsMatching(Predicate<? super Throwable> predicate);

Usage Examples:

// Ignore exceptions with specific message patterns
await().ignoreExceptionsMatching(ex -> 
        ex.getMessage() != null && ex.getMessage().contains("Connection refused"))
    .until(() -> networkService.isConnected());

// Ignore timeout exceptions but not other network errors
await().ignoreExceptionsMatching(ex -> 
        ex instanceof TimeoutException || 
        (ex instanceof IOException && ex.getMessage().contains("timeout")))
    .until(() -> remoteService.ping());

// Ignore exceptions from specific packages
await().ignoreExceptionsMatching(ex -> 
        ex.getClass().getPackage().getName().startsWith("com.external.unreliable"))
    .until(() -> externalApi.getData() != null);

Hamcrest Matcher-Based Filtering

Use Hamcrest matchers for sophisticated exception matching.

Matcher-Based Filtering

/**
 * Ignore exceptions matching the given Hamcrest matcher
 * @param matcher Hamcrest matcher for exception testing
 * @return ConditionFactory for further configuration
 */
ConditionFactory ignoreExceptionsMatching(Matcher<? super Throwable> matcher);

Usage Examples:

import static org.hamcrest.Matchers.*;

// Ignore exceptions that are instances of specific types
await().ignoreExceptionsMatching(
        anyOf(instanceOf(ConnectException.class), instanceOf(SocketTimeoutException.class)))
    .until(() -> tcpClient.connect());

// Ignore exceptions with messages containing specific text
await().ignoreExceptionsMatching(
        hasProperty("message", containsString("Service temporarily unavailable")))
    .until(() -> apiClient.getServiceStatus() == ServiceStatus.AVAILABLE);

// Complex matcher combining multiple conditions
await().ignoreExceptionsMatching(
        allOf(
            instanceOf(RuntimeException.class),
            hasProperty("message", not(containsString("fatal"))),
            hasProperty("cause", nullValue())
        ))
    .until(() -> volatileOperation.execute());

Uncaught Exception Handling

Control handling of uncaught exceptions from other threads.

Enable Uncaught Exception Catching

/**
 * Catch uncaught exceptions from other threads
 * Test will fail if any thread throws uncaught exception
 * @return ConditionFactory for further configuration
 */
ConditionFactory catchUncaughtExceptions();

Disable Uncaught Exception Catching

/**
 * Don't catch uncaught exceptions from other threads
 * Test will not fail due to uncaught exceptions in other threads
 * @return ConditionFactory for further configuration
 */
ConditionFactory dontCatchUncaughtExceptions();

Usage Examples:

// Fail fast if any background thread has problems
await().catchUncaughtExceptions()
    .until(() -> multiThreadedService.isProcessingComplete());

// Ignore problems in background threads
await().dontCatchUncaughtExceptions()
    .until(() -> mainOperation.isDone());

Global Exception Configuration

Set default exception handling behavior for all await statements.

Global Ignore Settings

/**
 * Set global default to ignore all exceptions
 * Affects all subsequent await statements
 */
static void ignoreExceptionsByDefault();

/**
 * Set global default to ignore specific exception type
 * @param exceptionType exception class to ignore globally
 */
static void ignoreExceptionByDefault(Class<? extends Throwable> exceptionType);

/**
 * Set global default to ignore exceptions matching predicate
 * @param predicate function to test exceptions globally
 */
static void ignoreExceptionsByDefaultMatching(Predicate<? super Throwable> predicate);

/**
 * Set global default to ignore exceptions matching matcher
 * @param matcher Hamcrest matcher for global exception testing
 */
static void ignoreExceptionsByDefaultMatching(Matcher<? super Throwable> matcher);

Global Uncaught Exception Settings

/**
 * Set global default to catch uncaught exceptions
 * All await statements will catch uncaught exceptions by default
 */
static void catchUncaughtExceptionsByDefault();

/**
 * Set global default to not catch uncaught exceptions
 * All await statements will ignore uncaught exceptions by default
 */
static void doNotCatchUncaughtExceptionsByDefault();

Global Configuration Examples:

// Set up global exception handling at test class level
@BeforeClass
public static void configureExceptionHandling() {
    // Ignore common network exceptions globally
    ignoreExceptionsByDefaultMatching(ex -> 
        ex instanceof ConnectException || 
        ex instanceof SocketTimeoutException);
    
    // Catch uncaught exceptions by default
    catchUncaughtExceptionsByDefault();
}

@AfterClass
public static void resetExceptionHandling() {
    reset(); // Reset all defaults
}

Exception Handling Patterns

Common patterns for different testing scenarios.

Database Testing

// Ignore database connectivity issues during startup
await().ignoreExceptionsMatching(ex ->
        ex instanceof SQLException ||
        ex instanceof DataAccessException ||
        (ex instanceof RuntimeException && 
         ex.getCause() instanceof SQLException))
    .atMost(60, SECONDS)
    .until(() -> {
        try (Connection conn = dataSource.getConnection()) {
            return conn.createStatement()
                .executeQuery("SELECT 1")
                .next();
        }
    });

Network Service Testing

// Ignore network-related exceptions
Predicate<Throwable> isNetworkException = ex ->
    ex instanceof ConnectException ||
    ex instanceof SocketTimeoutException ||
    ex instanceof UnknownHostException ||
    (ex instanceof IOException && 
     ex.getMessage().toLowerCase().contains("connection"));

await().ignoreExceptionsMatching(isNetworkException)
    .pollInterval(2, SECONDS)
    .atMost(5, MINUTES)
    .until(() -> httpClient.get("/api/status").getStatusCode() == 200);

Message Queue Testing

// Ignore message broker connection issues
await().ignoreExceptionsMatching(ex ->
        ex.getClass().getName().contains("JMSException") ||
        ex.getClass().getName().contains("AMQException") ||
        ex.getMessage().contains("broker not available"))
    .pollInterval(500, MILLISECONDS)
    .atMost(30, SECONDS)
    .until(() -> messageProducer.isConnected() && messageConsumer.isConnected());

Complex Exception Scenarios

// Combine multiple exception handling strategies
await().ignoreException(TimeoutException.class)  // Ignore timeouts
    .and().ignoreExceptionsMatching(ex ->         // Ignore retryable errors
        ex instanceof RetryableException ||
        (ex instanceof RuntimeException && 
         ex.getMessage().contains("retry")))
    .and().catchUncaughtExceptions()               // But catch uncaught exceptions
    .atMost(2, MINUTES)
    .pollInterval(new FibonacciPollInterval(
        Duration.ofMillis(100), 
        Duration.ofSeconds(5)))
    .until(() -> complexDistributedOperation.getStatus() == Status.COMPLETED);

Install with Tessl CLI

npx tessl i tessl/maven-org-awaitility--awaitility

docs

advanced-config.md

atomic-variables.md

condition-evaluation.md

core-await.md

exception-handling.md

field-reflection.md

index.md

timeout-polling.md

tile.json