0
# Exception Handling
1
2
Error handling and exception management for HTTP errors, JavaScript errors, element access failures, and connection problems with comprehensive error recovery strategies.
3
4
## Capabilities
5
6
### HTTP Status Code Exceptions
7
8
Handle HTTP error responses with detailed status information.
9
10
```java { .api }
11
public class FailingHttpStatusCodeException extends RuntimeException {
12
/**
13
* Get the HTTP status code that caused the exception
14
* @return the HTTP status code (e.g., 404, 500)
15
*/
16
public int getStatusCode();
17
18
/**
19
* Get the HTTP status message
20
* @return the status message from the server (e.g., "Not Found")
21
*/
22
public String getStatusMessage();
23
24
/**
25
* Get the complete web response that triggered this exception
26
* @return the WebResponse object with full response details
27
*/
28
public WebResponse getResponse();
29
30
/**
31
* Get the original web request
32
* @return the WebRequest that failed
33
*/
34
public WebRequest getRequest();
35
36
/**
37
* Get the response body content as string
38
* @return the error page content, if any
39
*/
40
public String getResponseBody();
41
}
42
```
43
44
**Usage Examples:**
45
46
```java
47
WebClient webClient = new WebClient();
48
49
// Enable HTTP status exceptions (default is true)
50
webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);
51
52
try {
53
HtmlPage page = webClient.getPage("https://example.com/nonexistent-page");
54
55
} catch (FailingHttpStatusCodeException e) {
56
int statusCode = e.getStatusCode();
57
String statusMessage = e.getStatusMessage();
58
WebResponse response = e.getResponse();
59
60
System.err.println("HTTP Error: " + statusCode + " " + statusMessage);
61
System.err.println("URL: " + response.getWebRequest().getUrl());
62
63
// Handle specific error codes
64
switch (statusCode) {
65
case 404:
66
System.err.println("Page not found - check URL");
67
break;
68
case 403:
69
System.err.println("Access forbidden - check authentication");
70
break;
71
case 500:
72
System.err.println("Server error - try again later");
73
String errorBody = e.getResponseBody();
74
System.err.println("Error details: " + errorBody);
75
break;
76
default:
77
System.err.println("Unexpected HTTP error");
78
}
79
}
80
81
// Alternative: disable exceptions for status codes
82
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
83
HtmlPage page = webClient.getPage("https://example.com/might-not-exist");
84
WebResponse response = page.getWebResponse();
85
if (response.getStatusCode() != 200) {
86
System.out.println("Request failed with status: " + response.getStatusCode());
87
}
88
```
89
90
### Element Access Exceptions
91
92
Handle missing or inaccessible DOM elements.
93
94
```java { .api }
95
public class ElementNotFoundException extends RuntimeException {
96
/**
97
* Get the element identifier that was not found
98
* @return the ID, name, or other identifier used in the search
99
*/
100
public String getElementIdentifier();
101
102
/**
103
* Get the search method that was used
104
* @return description of the search method (e.g., "by ID", "by name")
105
*/
106
public String getSearchMethod();
107
108
/**
109
* Get the page where the search failed
110
* @return the HtmlPage that was searched
111
*/
112
public HtmlPage getPage();
113
}
114
```
115
116
**Usage Examples:**
117
118
```java
119
HtmlPage page = webClient.getPage("https://example.com/form");
120
121
try {
122
// This will throw ElementNotFoundException if element doesn't exist
123
HtmlElement element = page.getElementById("nonExistentId");
124
125
} catch (ElementNotFoundException e) {
126
String identifier = e.getElementIdentifier();
127
String method = e.getSearchMethod();
128
System.err.println("Element not found: " + identifier + " (" + method + ")");
129
130
// Try alternative approach
131
try {
132
HtmlElement alternativeElement = page.getElementByName("alternativeName");
133
// Use alternative element
134
} catch (ElementNotFoundException e2) {
135
System.err.println("No alternative element found either");
136
}
137
}
138
139
// Safe element access pattern
140
HtmlElement safeElement = null;
141
try {
142
safeElement = page.getElementById("myElement");
143
} catch (ElementNotFoundException e) {
144
// Element doesn't exist, use default handling
145
System.out.println("Using default behavior - element not found");
146
}
147
148
if (safeElement != null) {
149
// Proceed with element operations
150
safeElement.click();
151
}
152
```
153
154
### JavaScript Execution Exceptions
155
156
Handle JavaScript runtime errors and execution failures.
157
158
```java { .api }
159
public class ScriptException extends RuntimeException {
160
/**
161
* Get the JavaScript source code that caused the error
162
* @return the JavaScript code snippet
163
*/
164
public String getScriptSourceCode();
165
166
/**
167
* Get the line number where the error occurred
168
* @return line number in the script
169
*/
170
public int getLineNumber();
171
172
/**
173
* Get the column number where the error occurred
174
* @return column number in the script
175
*/
176
public int getColumnNumber();
177
178
/**
179
* Get the page where the script error occurred
180
* @return the HtmlPage containing the script
181
*/
182
public HtmlPage getPage();
183
184
/**
185
* Get the underlying JavaScript error details
186
* @return detailed error information
187
*/
188
public String getScriptStackTrace();
189
}
190
191
public class JavaScriptException extends ScriptException {
192
// Specific JavaScript runtime errors
193
}
194
195
public class ScriptTimeoutException extends ScriptException {
196
/**
197
* Get the timeout value that was exceeded
198
* @return timeout in milliseconds
199
*/
200
public long getTimeoutValue();
201
202
/**
203
* Get the actual execution time
204
* @return execution time in milliseconds
205
*/
206
public long getExecutionTime();
207
}
208
```
209
210
**Usage Examples:**
211
212
```java
213
WebClient webClient = new WebClient();
214
webClient.getOptions().setJavaScriptEnabled(true);
215
216
// Enable JavaScript error exceptions
217
webClient.getOptions().setThrowExceptionOnScriptError(true);
218
219
try {
220
HtmlPage page = webClient.getPage("https://example.com/js-heavy-page");
221
222
// Wait for JavaScript to complete
223
webClient.waitForBackgroundJavaScript(5000);
224
225
} catch (ScriptException e) {
226
System.err.println("JavaScript Error: " + e.getMessage());
227
System.err.println("Line: " + e.getLineNumber() + ", Column: " + e.getColumnNumber());
228
System.err.println("Source: " + e.getScriptSourceCode());
229
230
// Handle specific script exception types
231
if (e instanceof ScriptTimeoutException) {
232
ScriptTimeoutException timeout = (ScriptTimeoutException) e;
233
System.err.println("Script timed out after " + timeout.getExecutionTime() + "ms");
234
System.err.println("Timeout limit was " + timeout.getTimeoutValue() + "ms");
235
}
236
237
} catch (JavaScriptException e) {
238
System.err.println("JavaScript runtime error: " + e.getMessage());
239
System.err.println("Stack trace: " + e.getScriptStackTrace());
240
}
241
242
// Alternative: handle errors with listener instead of exceptions
243
webClient.getOptions().setThrowExceptionOnScriptError(false);
244
webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {
245
@Override
246
public void scriptException(HtmlPage page, ScriptException scriptException) {
247
System.err.println("JS Error on " + page.getUrl() + ": " + scriptException.getMessage());
248
}
249
250
@Override
251
public void timeoutError(HtmlPage page, long allowedTime, long executionTime) {
252
System.err.println("JS Timeout on " + page.getUrl() + ": " + executionTime + "ms");
253
}
254
255
@Override
256
public void malformedScriptURL(HtmlPage page, String url, MalformedURLException exception) {
257
System.err.println("Malformed script URL: " + url);
258
}
259
260
@Override
261
public void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception) {
262
System.err.println("Failed to load script: " + scriptUrl);
263
}
264
});
265
```
266
267
### Connection and Network Exceptions
268
269
Handle network connectivity and connection problems.
270
271
```java { .api }
272
public class ConnectTimeoutException extends IOException {
273
/**
274
* Get the timeout value that was exceeded
275
* @return timeout in milliseconds
276
*/
277
public int getTimeout();
278
279
/**
280
* Get the URL that failed to connect
281
* @return the target URL
282
*/
283
public URL getURL();
284
}
285
286
public class UnknownHostException extends IOException {
287
/**
288
* Get the hostname that could not be resolved
289
* @return the unknown hostname
290
*/
291
public String getHostname();
292
}
293
```
294
295
**Usage Examples:**
296
297
```java
298
WebClient webClient = new WebClient();
299
300
// Set connection timeout
301
webClient.getOptions().setTimeout(10000); // 10 seconds
302
303
try {
304
HtmlPage page = webClient.getPage("https://slow-server.example.com");
305
306
} catch (ConnectTimeoutException e) {
307
System.err.println("Connection timed out after " + e.getTimeout() + "ms");
308
System.err.println("Failed URL: " + e.getURL());
309
310
// Retry with longer timeout
311
webClient.getOptions().setTimeout(30000);
312
try {
313
HtmlPage retryPage = webClient.getPage(e.getURL());
314
System.out.println("Retry successful");
315
} catch (Exception retryException) {
316
System.err.println("Retry also failed: " + retryException.getMessage());
317
}
318
319
} catch (UnknownHostException e) {
320
System.err.println("Cannot resolve hostname: " + e.getHostname());
321
System.err.println("Check network connection and DNS settings");
322
323
} catch (IOException e) {
324
System.err.println("Network error: " + e.getMessage());
325
}
326
```
327
328
### Window and Navigation Exceptions
329
330
Handle window management and navigation errors.
331
332
```java { .api }
333
public class WebWindowNotFoundException extends RuntimeException {
334
/**
335
* Get the window name that was not found
336
* @return the requested window name
337
*/
338
public String getWindowName();
339
340
/**
341
* Get the WebClient where the search failed
342
* @return the WebClient instance
343
*/
344
public WebClient getWebClient();
345
}
346
```
347
348
**Usage Examples:**
349
350
```java
351
WebClient webClient = new WebClient();
352
353
try {
354
// This might throw if window name doesn't exist
355
WebWindow targetWindow = webClient.openTargetWindow(
356
webClient.getCurrentWindow(),
357
"nonExistentWindow",
358
"default"
359
);
360
361
} catch (WebWindowNotFoundException e) {
362
String windowName = e.getWindowName();
363
System.err.println("Window not found: " + windowName);
364
365
// List available windows
366
List<WebWindow> availableWindows = webClient.getWebWindows();
367
System.out.println("Available windows:");
368
for (WebWindow window : availableWindows) {
369
System.out.println(" - " + window.getName());
370
}
371
}
372
```
373
374
### Comprehensive Error Handling Strategy
375
376
Best practices for robust error handling in HtmlUnit applications.
377
378
**Usage Examples:**
379
380
```java
381
public class RobustWebClient {
382
private WebClient webClient;
383
384
public RobustWebClient() {
385
this.webClient = new WebClient();
386
configureErrorHandling();
387
}
388
389
private void configureErrorHandling() {
390
// Configure timeouts
391
webClient.getOptions().setTimeout(15000);
392
393
// Handle HTTP errors gracefully
394
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
395
396
// Handle JavaScript errors without failing
397
webClient.getOptions().setThrowExceptionOnScriptError(false);
398
399
// Set up JavaScript error listener
400
webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {
401
@Override
402
public void scriptException(HtmlPage page, ScriptException scriptException) {
403
System.warn("JS Error on " + page.getUrl() + ": " + scriptException.getMessage());
404
}
405
406
@Override
407
public void timeoutError(HtmlPage page, long allowedTime, long executionTime) {
408
System.warn("JS Timeout on " + page.getUrl());
409
}
410
411
@Override
412
public void malformedScriptURL(HtmlPage page, String url, MalformedURLException exception) {
413
System.warn("Malformed script URL: " + url);
414
}
415
416
@Override
417
public void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception) {
418
System.warn("Failed to load script: " + scriptUrl);
419
}
420
});
421
}
422
423
public HtmlPage safeGetPage(String url, int maxRetries) {
424
Exception lastException = null;
425
426
for (int attempt = 1; attempt <= maxRetries; attempt++) {
427
try {
428
HtmlPage page = webClient.getPage(url);
429
WebResponse response = page.getWebResponse();
430
431
if (response.getStatusCode() == 200) {
432
return page;
433
} else {
434
System.warn("Attempt " + attempt + " failed with status: " + response.getStatusCode());
435
}
436
437
} catch (ConnectTimeoutException e) {
438
lastException = e;
439
System.warn("Attempt " + attempt + " timed out, retrying...");
440
441
// Increase timeout for next attempt
442
webClient.getOptions().setTimeout(webClient.getOptions().getTimeout() + 5000);
443
444
} catch (UnknownHostException e) {
445
// Don't retry DNS failures
446
throw new RuntimeException("Cannot resolve host: " + url, e);
447
448
} catch (IOException e) {
449
lastException = e;
450
System.warn("Attempt " + attempt + " failed: " + e.getMessage());
451
452
if (attempt < maxRetries) {
453
try {
454
Thread.sleep(1000 * attempt); // Exponential backoff
455
} catch (InterruptedException ie) {
456
Thread.currentThread().interrupt();
457
break;
458
}
459
}
460
}
461
}
462
463
throw new RuntimeException("Failed to load page after " + maxRetries + " attempts", lastException);
464
}
465
466
public HtmlElement safeGetElement(HtmlPage page, String id, String... alternativeIds) {
467
// Try primary ID
468
try {
469
return page.getElementById(id);
470
} catch (ElementNotFoundException e) {
471
// Try alternative IDs
472
for (String altId : alternativeIds) {
473
try {
474
return page.getElementById(altId);
475
} catch (ElementNotFoundException e2) {
476
// Continue to next alternative
477
}
478
}
479
}
480
481
// Element not found with any ID
482
System.warn("Element not found: " + id + " (tried alternatives: " + Arrays.toString(alternativeIds) + ")");
483
return null;
484
}
485
486
public void close() {
487
if (webClient != null) {
488
webClient.close();
489
}
490
}
491
}
492
493
// Usage
494
RobustWebClient client = new RobustWebClient();
495
try {
496
HtmlPage page = client.safeGetPage("https://example.com", 3);
497
HtmlElement element = client.safeGetElement(page, "primaryId", "secondaryId", "fallbackId");
498
499
if (element != null) {
500
element.click();
501
}
502
503
} finally {
504
client.close();
505
}
506
```