CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-htmlunit--htmlunit

A headless browser for Java programs that provides web automation, form handling, JavaScript execution, and DOM manipulation capabilities.

Pending
Overview
Eval results
Files

exceptions.mddocs/

Exception Handling

Error handling and exception management for HTTP errors, JavaScript errors, element access failures, and connection problems with comprehensive error recovery strategies.

Capabilities

HTTP Status Code Exceptions

Handle HTTP error responses with detailed status information.

public class FailingHttpStatusCodeException extends RuntimeException {
    /**
     * Get the HTTP status code that caused the exception
     * @return the HTTP status code (e.g., 404, 500)
     */
    public int getStatusCode();
    
    /**
     * Get the HTTP status message
     * @return the status message from the server (e.g., "Not Found")
     */
    public String getStatusMessage();
    
    /**
     * Get the complete web response that triggered this exception
     * @return the WebResponse object with full response details
     */
    public WebResponse getResponse();
    
    /**
     * Get the original web request
     * @return the WebRequest that failed
     */
    public WebRequest getRequest();
    
    /**
     * Get the response body content as string
     * @return the error page content, if any
     */
    public String getResponseBody();
}

Usage Examples:

WebClient webClient = new WebClient();

// Enable HTTP status exceptions (default is true)
webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);

try {
    HtmlPage page = webClient.getPage("https://example.com/nonexistent-page");
    
} catch (FailingHttpStatusCodeException e) {
    int statusCode = e.getStatusCode();
    String statusMessage = e.getStatusMessage();
    WebResponse response = e.getResponse();
    
    System.err.println("HTTP Error: " + statusCode + " " + statusMessage);
    System.err.println("URL: " + response.getWebRequest().getUrl());
    
    // Handle specific error codes
    switch (statusCode) {
        case 404:
            System.err.println("Page not found - check URL");
            break;
        case 403:
            System.err.println("Access forbidden - check authentication");
            break;
        case 500:
            System.err.println("Server error - try again later");
            String errorBody = e.getResponseBody();
            System.err.println("Error details: " + errorBody);
            break;
        default:
            System.err.println("Unexpected HTTP error");
    }
}

// Alternative: disable exceptions for status codes
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = webClient.getPage("https://example.com/might-not-exist");
WebResponse response = page.getWebResponse();
if (response.getStatusCode() != 200) {
    System.out.println("Request failed with status: " + response.getStatusCode());
}

Element Access Exceptions

Handle missing or inaccessible DOM elements.

public class ElementNotFoundException extends RuntimeException {
    /**
     * Get the element identifier that was not found
     * @return the ID, name, or other identifier used in the search
     */
    public String getElementIdentifier();
    
    /**
     * Get the search method that was used
     * @return description of the search method (e.g., "by ID", "by name")
     */
    public String getSearchMethod();
    
    /**
     * Get the page where the search failed
     * @return the HtmlPage that was searched
     */
    public HtmlPage getPage();
}

Usage Examples:

HtmlPage page = webClient.getPage("https://example.com/form");

try {
    // This will throw ElementNotFoundException if element doesn't exist
    HtmlElement element = page.getElementById("nonExistentId");
    
} catch (ElementNotFoundException e) {
    String identifier = e.getElementIdentifier();
    String method = e.getSearchMethod();
    System.err.println("Element not found: " + identifier + " (" + method + ")");
    
    // Try alternative approach
    try {
        HtmlElement alternativeElement = page.getElementByName("alternativeName");
        // Use alternative element
    } catch (ElementNotFoundException e2) {
        System.err.println("No alternative element found either");
    }
}

// Safe element access pattern
HtmlElement safeElement = null;
try {
    safeElement = page.getElementById("myElement");
} catch (ElementNotFoundException e) {
    // Element doesn't exist, use default handling
    System.out.println("Using default behavior - element not found");
}

if (safeElement != null) {
    // Proceed with element operations
    safeElement.click();
}

JavaScript Execution Exceptions

Handle JavaScript runtime errors and execution failures.

public class ScriptException extends RuntimeException {
    /**
     * Get the JavaScript source code that caused the error
     * @return the JavaScript code snippet
     */
    public String getScriptSourceCode();
    
    /**
     * Get the line number where the error occurred
     * @return line number in the script
     */
    public int getLineNumber();
    
    /**
     * Get the column number where the error occurred
     * @return column number in the script
     */
    public int getColumnNumber();
    
    /**
     * Get the page where the script error occurred
     * @return the HtmlPage containing the script
     */
    public HtmlPage getPage();
    
    /**
     * Get the underlying JavaScript error details
     * @return detailed error information
     */
    public String getScriptStackTrace();
}

public class JavaScriptException extends ScriptException {
    // Specific JavaScript runtime errors
}

public class ScriptTimeoutException extends ScriptException {
    /**
     * Get the timeout value that was exceeded
     * @return timeout in milliseconds
     */
    public long getTimeoutValue();
    
    /**
     * Get the actual execution time
     * @return execution time in milliseconds
     */
    public long getExecutionTime();
}

Usage Examples:

WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true);

// Enable JavaScript error exceptions
webClient.getOptions().setThrowExceptionOnScriptError(true);

try {
    HtmlPage page = webClient.getPage("https://example.com/js-heavy-page");
    
    // Wait for JavaScript to complete
    webClient.waitForBackgroundJavaScript(5000);
    
} catch (ScriptException e) {
    System.err.println("JavaScript Error: " + e.getMessage());
    System.err.println("Line: " + e.getLineNumber() + ", Column: " + e.getColumnNumber());
    System.err.println("Source: " + e.getScriptSourceCode());
    
    // Handle specific script exception types
    if (e instanceof ScriptTimeoutException) {
        ScriptTimeoutException timeout = (ScriptTimeoutException) e;
        System.err.println("Script timed out after " + timeout.getExecutionTime() + "ms");
        System.err.println("Timeout limit was " + timeout.getTimeoutValue() + "ms");
    }
    
} catch (JavaScriptException e) {
    System.err.println("JavaScript runtime error: " + e.getMessage());
    System.err.println("Stack trace: " + e.getScriptStackTrace());
}

// Alternative: handle errors with listener instead of exceptions
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {
    @Override
    public void scriptException(HtmlPage page, ScriptException scriptException) {
        System.err.println("JS Error on " + page.getUrl() + ": " + scriptException.getMessage());
    }
    
    @Override
    public void timeoutError(HtmlPage page, long allowedTime, long executionTime) {
        System.err.println("JS Timeout on " + page.getUrl() + ": " + executionTime + "ms");
    }
    
    @Override
    public void malformedScriptURL(HtmlPage page, String url, MalformedURLException exception) {
        System.err.println("Malformed script URL: " + url);
    }
    
    @Override
    public void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception) {
        System.err.println("Failed to load script: " + scriptUrl);
    }
});

Connection and Network Exceptions

Handle network connectivity and connection problems.

public class ConnectTimeoutException extends IOException {
    /**
     * Get the timeout value that was exceeded
     * @return timeout in milliseconds
     */
    public int getTimeout();
    
    /**
     * Get the URL that failed to connect
     * @return the target URL
     */
    public URL getURL();
}

public class UnknownHostException extends IOException {
    /**
     * Get the hostname that could not be resolved
     * @return the unknown hostname
     */
    public String getHostname();
}

Usage Examples:

WebClient webClient = new WebClient();

// Set connection timeout
webClient.getOptions().setTimeout(10000); // 10 seconds

try {
    HtmlPage page = webClient.getPage("https://slow-server.example.com");
    
} catch (ConnectTimeoutException e) {
    System.err.println("Connection timed out after " + e.getTimeout() + "ms");
    System.err.println("Failed URL: " + e.getURL());
    
    // Retry with longer timeout
    webClient.getOptions().setTimeout(30000);
    try {
        HtmlPage retryPage = webClient.getPage(e.getURL());
        System.out.println("Retry successful");
    } catch (Exception retryException) {
        System.err.println("Retry also failed: " + retryException.getMessage());
    }
    
} catch (UnknownHostException e) {
    System.err.println("Cannot resolve hostname: " + e.getHostname());
    System.err.println("Check network connection and DNS settings");
    
} catch (IOException e) {
    System.err.println("Network error: " + e.getMessage());
}

Window and Navigation Exceptions

Handle window management and navigation errors.

public class WebWindowNotFoundException extends RuntimeException {
    /**
     * Get the window name that was not found
     * @return the requested window name
     */
    public String getWindowName();
    
    /**
     * Get the WebClient where the search failed
     * @return the WebClient instance
     */
    public WebClient getWebClient();
}

Usage Examples:

WebClient webClient = new WebClient();

try {
    // This might throw if window name doesn't exist
    WebWindow targetWindow = webClient.openTargetWindow(
        webClient.getCurrentWindow(), 
        "nonExistentWindow", 
        "default"
    );
    
} catch (WebWindowNotFoundException e) {
    String windowName = e.getWindowName();
    System.err.println("Window not found: " + windowName);
    
    // List available windows
    List<WebWindow> availableWindows = webClient.getWebWindows();
    System.out.println("Available windows:");
    for (WebWindow window : availableWindows) {
        System.out.println("  - " + window.getName());
    }
}

Comprehensive Error Handling Strategy

Best practices for robust error handling in HtmlUnit applications.

Usage Examples:

public class RobustWebClient {
    private WebClient webClient;
    
    public RobustWebClient() {
        this.webClient = new WebClient();
        configureErrorHandling();
    }
    
    private void configureErrorHandling() {
        // Configure timeouts
        webClient.getOptions().setTimeout(15000);
        
        // Handle HTTP errors gracefully
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        
        // Handle JavaScript errors without failing
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        
        // Set up JavaScript error listener
        webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {
            @Override
            public void scriptException(HtmlPage page, ScriptException scriptException) {
                System.warn("JS Error on " + page.getUrl() + ": " + scriptException.getMessage());
            }
            
            @Override
            public void timeoutError(HtmlPage page, long allowedTime, long executionTime) {
                System.warn("JS Timeout on " + page.getUrl());
            }
            
            @Override
            public void malformedScriptURL(HtmlPage page, String url, MalformedURLException exception) {
                System.warn("Malformed script URL: " + url);
            }
            
            @Override
            public void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception) {
                System.warn("Failed to load script: " + scriptUrl);
            }
        });
    }
    
    public HtmlPage safeGetPage(String url, int maxRetries) {
        Exception lastException = null;
        
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                HtmlPage page = webClient.getPage(url);
                WebResponse response = page.getWebResponse();
                
                if (response.getStatusCode() == 200) {
                    return page;
                } else {
                    System.warn("Attempt " + attempt + " failed with status: " + response.getStatusCode());
                }
                
            } catch (ConnectTimeoutException e) {
                lastException = e;
                System.warn("Attempt " + attempt + " timed out, retrying...");
                
                // Increase timeout for next attempt
                webClient.getOptions().setTimeout(webClient.getOptions().getTimeout() + 5000);
                
            } catch (UnknownHostException e) {
                // Don't retry DNS failures
                throw new RuntimeException("Cannot resolve host: " + url, e);
                
            } catch (IOException e) {
                lastException = e;
                System.warn("Attempt " + attempt + " failed: " + e.getMessage());
                
                if (attempt < maxRetries) {
                    try {
                        Thread.sleep(1000 * attempt); // Exponential backoff
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }
        
        throw new RuntimeException("Failed to load page after " + maxRetries + " attempts", lastException);
    }
    
    public HtmlElement safeGetElement(HtmlPage page, String id, String... alternativeIds) {
        // Try primary ID
        try {
            return page.getElementById(id);
        } catch (ElementNotFoundException e) {
            // Try alternative IDs
            for (String altId : alternativeIds) {
                try {
                    return page.getElementById(altId);
                } catch (ElementNotFoundException e2) {
                    // Continue to next alternative
                }
            }
        }
        
        // Element not found with any ID
        System.warn("Element not found: " + id + " (tried alternatives: " + Arrays.toString(alternativeIds) + ")");
        return null;
    }
    
    public void close() {
        if (webClient != null) {
            webClient.close();
        }
    }
}

// Usage
RobustWebClient client = new RobustWebClient();
try {
    HtmlPage page = client.safeGetPage("https://example.com", 3);
    HtmlElement element = client.safeGetElement(page, "primaryId", "secondaryId", "fallbackId");
    
    if (element != null) {
        element.click();
    }
    
} finally {
    client.close();
}

Install with Tessl CLI

npx tessl i tessl/maven-org-htmlunit--htmlunit

docs

cookies.md

exceptions.md

forms.md

http.md

index.md

javascript.md

page-dom.md

web-client.md

windows.md

tile.json