0
# Exception Handling
1
2
Comprehensive exception hierarchy for robust error handling in industrial communication with Apache PLC4X Java API.
3
4
## Exception Hierarchy
5
6
### Base Exception Classes
7
8
```java { .api }
9
/**
10
* Base checked exception for all PLC4X operations
11
*/
12
public class PlcException extends Exception {
13
/**
14
* Create exception with message
15
* @param message Error description
16
*/
17
public PlcException(String message);
18
19
/**
20
* Create exception with message and cause
21
* @param message Error description
22
* @param cause Underlying cause
23
*/
24
public PlcException(String message, Throwable cause);
25
26
/**
27
* Create exception with cause
28
* @param cause Underlying cause
29
*/
30
public PlcException(Throwable cause);
31
32
/**
33
* Create exception with full control over suppression and stack trace
34
* @param message Error description
35
* @param cause Underlying cause
36
* @param enableSuppression Whether suppression is enabled
37
* @param writableStackTrace Whether stack trace is writable
38
*/
39
public PlcException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace);
40
}
41
42
/**
43
* Base runtime exception for all PLC4X operations
44
*/
45
public class PlcRuntimeException extends RuntimeException {
46
/**
47
* Create runtime exception with message
48
* @param message Error description
49
*/
50
public PlcRuntimeException(String message);
51
52
/**
53
* Create runtime exception with message and cause
54
* @param message Error description
55
* @param cause Underlying cause
56
*/
57
public PlcRuntimeException(String message, Throwable cause);
58
59
/**
60
* Create runtime exception with cause
61
* @param cause Underlying cause
62
*/
63
public PlcRuntimeException(Throwable cause);
64
}
65
```
66
67
## Connection-Related Exceptions
68
69
### PlcConnectionException
70
71
```java { .api }
72
/**
73
* Exception thrown when connection operations fail
74
*/
75
public class PlcConnectionException extends PlcException {
76
/**
77
* Create connection exception with message
78
* @param message Error description
79
*/
80
public PlcConnectionException(String message);
81
82
/**
83
* Create connection exception with message and cause
84
* @param message Error description
85
* @param cause Underlying cause
86
*/
87
public PlcConnectionException(String message, Throwable cause);
88
89
/**
90
* Create connection exception with cause
91
* @param cause Underlying cause
92
*/
93
public PlcConnectionException(Throwable cause);
94
95
/**
96
* Create connection exception with full control over suppression and stack trace
97
* @param message Error description
98
* @param cause Underlying cause
99
* @param enableSuppression Whether suppression is enabled
100
* @param writableStackTrace Whether stack trace is writable
101
*/
102
public PlcConnectionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace);
103
}
104
```
105
106
**Common Causes:**
107
- Network connectivity issues
108
- Invalid connection URLs
109
- Authentication failures
110
- PLC not responding
111
- Protocol negotiation failures
112
113
## I/O Related Exceptions
114
115
### PlcIoException
116
117
```java { .api }
118
/**
119
* Exception thrown when I/O operations fail
120
*/
121
public class PlcIoException extends PlcException {
122
/**
123
* Create I/O exception with message
124
* @param message Error description
125
*/
126
public PlcIoException(String message);
127
128
/**
129
* Create I/O exception with message and cause
130
* @param message Error description
131
* @param cause Underlying cause
132
*/
133
public PlcIoException(String message, Throwable cause);
134
}
135
```
136
137
**Common Causes:**
138
- Network timeouts
139
- Socket errors
140
- Communication interruptions
141
- Buffer overflows
142
- Serialization/deserialization errors
143
144
## Protocol-Related Exceptions
145
146
### PlcProtocolException
147
148
```java { .api }
149
/**
150
* Exception thrown when protocol-level errors occur
151
*/
152
public class PlcProtocolException extends PlcException {
153
/**
154
* Create protocol exception with message
155
* @param message Error description
156
*/
157
public PlcProtocolException(String message);
158
159
/**
160
* Create protocol exception with message and cause
161
* @param message Error description
162
* @param cause Underlying cause
163
*/
164
public PlcProtocolException(String message, Throwable cause);
165
}
166
```
167
168
### PlcProtocolTimeoutException
169
170
```java { .api }
171
/**
172
* Exception thrown when protocol operations timeout
173
*/
174
public class PlcProtocolTimeoutException extends PlcProtocolException {
175
/**
176
* Create protocol timeout exception with message
177
* @param message Error description
178
*/
179
public PlcProtocolTimeoutException(String message);
180
}
181
```
182
183
### PlcProtocolPayloadTooBigException
184
185
```java { .api }
186
/**
187
* Exception thrown when protocol payload exceeds size limits
188
*/
189
public class PlcProtocolPayloadTooBigException extends PlcProtocolException {
190
/**
191
* Create payload too big exception with message
192
* @param message Error description
193
*/
194
public PlcProtocolPayloadTooBigException(String message);
195
}
196
```
197
198
## Timeout Exceptions
199
200
### PlcTimeoutException
201
202
```java { .api }
203
/**
204
* Exception thrown when operations timeout
205
*/
206
public class PlcTimeoutException extends PlcException {
207
/**
208
* Create timeout exception with message
209
* @param message Error description
210
*/
211
public PlcTimeoutException(String message);
212
213
/**
214
* Create timeout exception with message and cause
215
* @param message Error description
216
* @param cause Underlying cause
217
*/
218
public PlcTimeoutException(String message, Throwable cause);
219
}
220
```
221
222
## Feature Support Exceptions
223
224
### PlcNotImplementedException
225
226
```java { .api }
227
/**
228
* Exception thrown when requested feature is not implemented
229
*/
230
public class PlcNotImplementedException extends PlcException {
231
/**
232
* Create not implemented exception with message
233
* @param message Error description
234
*/
235
public PlcNotImplementedException(String message);
236
}
237
```
238
239
### PlcUnsupportedOperationException
240
241
```java { .api }
242
/**
243
* Exception thrown when operation is not supported by the driver/protocol
244
*/
245
public class PlcUnsupportedOperationException extends PlcException {
246
/**
247
* Create unsupported operation exception with message
248
* @param message Error description
249
*/
250
public PlcUnsupportedOperationException(String message);
251
}
252
```
253
254
### PlcUnsupportedDataTypeException
255
256
```java { .api }
257
/**
258
* Exception thrown when data type is not supported
259
*/
260
public class PlcUnsupportedDataTypeException extends PlcException {
261
/**
262
* Create unsupported data type exception with message
263
* @param message Error description
264
*/
265
public PlcUnsupportedDataTypeException(String message);
266
}
267
```
268
269
### PlcUnsupportedProtocolException
270
271
```java { .api }
272
/**
273
* Exception thrown when protocol is not supported
274
*/
275
public class PlcUnsupportedProtocolException extends PlcConnectionException {
276
/**
277
* Create unsupported protocol exception with message
278
* @param message Error description
279
*/
280
public PlcUnsupportedProtocolException(String message);
281
}
282
```
283
284
## Tag-Related Exceptions
285
286
### PlcInvalidTagException
287
288
```java { .api }
289
/**
290
* Exception thrown when tag address is invalid
291
*/
292
public class PlcInvalidTagException extends PlcException {
293
/**
294
* Create invalid tag exception with message
295
* @param message Error description
296
*/
297
public PlcInvalidTagException(String message);
298
299
/**
300
* Create invalid tag exception with message and cause
301
* @param message Error description
302
* @param cause Underlying cause
303
*/
304
public PlcInvalidTagException(String message, Throwable cause);
305
}
306
```
307
308
### PlcTagNotFoundException
309
310
```java { .api }
311
/**
312
* Exception thrown when tag is not found in PLC
313
*/
314
public class PlcTagNotFoundException extends PlcException {
315
/**
316
* Create tag not found exception with message
317
* @param message Error description
318
*/
319
public PlcTagNotFoundException(String message);
320
}
321
```
322
323
### PlcTagRangeException
324
325
```java { .api }
326
/**
327
* Exception thrown when tag range is invalid or out of bounds
328
*/
329
public class PlcTagRangeException extends PlcException {
330
/**
331
* Create tag range exception with message
332
* @param message Error description
333
*/
334
public PlcTagRangeException(String message);
335
}
336
```
337
338
## Data Type Exceptions
339
340
### PlcIncompatibleDatatypeException
341
342
```java { .api }
343
/**
344
* Exception thrown when data type conversion fails
345
*/
346
public class PlcIncompatibleDatatypeException extends PlcException {
347
/**
348
* Create incompatible datatype exception with message
349
* @param message Error description
350
*/
351
public PlcIncompatibleDatatypeException(String message);
352
353
/**
354
* Create incompatible datatype exception with message and cause
355
* @param message Error description
356
* @param cause Underlying cause
357
*/
358
public PlcIncompatibleDatatypeException(String message, Throwable cause);
359
}
360
```
361
362
**Usage Examples:**
363
364
```java
365
import org.apache.plc4x.java.DefaultPlcDriverManager;
366
import org.apache.plc4x.java.api.PlcConnection;
367
import org.apache.plc4x.java.api.exceptions.*;
368
import org.apache.plc4x.java.api.messages.*;
369
370
// Connection exception handling
371
PlcDriverManager driverManager = new DefaultPlcDriverManager();
372
try {
373
PlcConnection connection = driverManager.getConnection("invalid-protocol://192.168.1.100");
374
connection.connect();
375
} catch (PlcUnsupportedProtocolException e) {
376
System.err.println("Protocol not supported: " + e.getMessage());
377
} catch (PlcConnectionException e) {
378
System.err.println("Connection failed: " + e.getMessage());
379
// Log full stack trace for debugging
380
e.printStackTrace();
381
}
382
383
// Comprehensive error handling for read operations
384
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
385
connection.connect();
386
387
PlcReadRequest readRequest = connection.readRequestBuilder()
388
.addTagAddress("sensor1", "holding-register:1")
389
.addTagAddress("invalid_tag", "invalid-address")
390
.build();
391
392
try {
393
PlcReadResponse response = readRequest.execute().get();
394
395
// Handle individual tag response codes
396
for (String tagName : response.getTagNames()) {
397
try {
398
PlcResponseCode code = response.getResponseCode(tagName);
399
switch (code) {
400
case OK:
401
int value = response.getInteger(tagName);
402
System.out.println(tagName + ": " + value);
403
break;
404
case NOT_FOUND:
405
System.err.println("Tag not found: " + tagName);
406
break;
407
case ACCESS_DENIED:
408
System.err.println("Access denied for tag: " + tagName);
409
break;
410
case INVALID_ADDRESS:
411
System.err.println("Invalid address for tag: " + tagName);
412
break;
413
case INVALID_DATATYPE:
414
System.err.println("Invalid data type for tag: " + tagName);
415
break;
416
default:
417
System.err.println("Error reading " + tagName + ": " + code);
418
break;
419
}
420
} catch (PlcIncompatibleDatatypeException e) {
421
System.err.println("Data type conversion failed for " + tagName + ": " + e.getMessage());
422
}
423
}
424
425
} catch (PlcTimeoutException e) {
426
System.err.println("Read operation timed out: " + e.getMessage());
427
} catch (PlcIoException e) {
428
System.err.println("I/O error during read: " + e.getMessage());
429
} catch (PlcProtocolException e) {
430
System.err.println("Protocol error: " + e.getMessage());
431
}
432
433
} catch (PlcConnectionException e) {
434
System.err.println("Connection error: " + e.getMessage());
435
}
436
437
// Write operation error handling
438
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
439
connection.connect();
440
441
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
442
.addTagAddress("setpoint", "DB1.DBD0:REAL", 25.5f)
443
.addTagAddress("readonly", "DB1.DBD4:REAL", 30.0f) // Might be read-only
444
.build();
445
446
try {
447
PlcWriteResponse response = writeRequest.execute().get();
448
449
for (String tagName : response.getTagNames()) {
450
PlcResponseCode code = response.getResponseCode(tagName);
451
switch (code) {
452
case OK:
453
System.out.println("Successfully wrote " + tagName);
454
break;
455
case ACCESS_DENIED:
456
System.err.println("Write access denied for " + tagName + " (tag might be read-only)");
457
break;
458
case INVALID_DATA:
459
System.err.println("Invalid data value for " + tagName);
460
break;
461
case INVALID_DATATYPE:
462
System.err.println("Data type mismatch for " + tagName);
463
break;
464
default:
465
System.err.println("Write failed for " + tagName + ": " + code);
466
break;
467
}
468
}
469
470
} catch (PlcProtocolPayloadTooBigException e) {
471
System.err.println("Write payload too large: " + e.getMessage());
472
} catch (PlcProtocolTimeoutException e) {
473
System.err.println("Protocol timeout during write: " + e.getMessage());
474
}
475
476
} catch (PlcUnsupportedOperationException e) {
477
System.err.println("Write operations not supported by this driver: " + e.getMessage());
478
}
479
480
// Subscription error handling
481
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
482
connection.connect();
483
484
// Check capabilities first
485
if (!connection.getMetadata().isSubscribeSupported()) {
486
throw new PlcUnsupportedOperationException("Subscriptions not supported");
487
}
488
489
Consumer<PlcSubscriptionEvent> eventConsumer = event -> {
490
try {
491
for (String tagName : event.getTagNames()) {
492
if (event.getResponseCode(tagName) == PlcResponseCode.OK) {
493
int value = event.getInteger(tagName);
494
System.out.println("Event - " + tagName + ": " + value);
495
}
496
}
497
} catch (PlcIncompatibleDatatypeException e) {
498
System.err.println("Data conversion error in event: " + e.getMessage());
499
}
500
};
501
502
try {
503
PlcSubscriptionRequest subscriptionRequest = connection.subscriptionRequestBuilder()
504
.addCyclicTagAddress("sensor", "holding-register:1", Duration.ofSeconds(1))
505
.setConsumer(eventConsumer)
506
.build();
507
508
PlcSubscriptionResponse response = subscriptionRequest.execute().get();
509
510
if (response.getResponseCode("sensor") != PlcResponseCode.OK) {
511
System.err.println("Subscription failed: " + response.getResponseCode("sensor"));
512
}
513
514
Thread.sleep(10000); // Monitor for 10 seconds
515
516
} catch (PlcNotImplementedException e) {
517
System.err.println("Cyclic subscriptions not implemented: " + e.getMessage());
518
} catch (PlcUnsupportedDataTypeException e) {
519
System.err.println("Data type not supported for subscription: " + e.getMessage());
520
}
521
522
} catch (PlcUnsupportedOperationException e) {
523
System.err.println("Subscriptions not supported: " + e.getMessage());
524
}
525
526
// Tag parsing error handling
527
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
528
connection.connect();
529
530
try {
531
// Try to parse a tag address
532
Optional<PlcTag> tag = connection.parseTagAddress("DB1.INVALID_SYNTAX");
533
if (tag.isPresent()) {
534
System.out.println("Tag parsed successfully");
535
} else {
536
System.err.println("Tag parsing returned empty result");
537
}
538
} catch (PlcInvalidTagException e) {
539
System.err.println("Invalid tag syntax: " + e.getMessage());
540
}
541
542
// Try to parse tag values
543
try {
544
PlcTag validTag = connection.parseTagAddress("DB1.DBD0:REAL").orElseThrow();
545
Optional<PlcValue> value = connection.parseTagValue(validTag, "invalid_float_value");
546
if (!value.isPresent()) {
547
System.err.println("Value parsing failed");
548
}
549
} catch (PlcInvalidTagException e) {
550
System.err.println("Tag validation failed: " + e.getMessage());
551
} catch (PlcIncompatibleDatatypeException e) {
552
System.err.println("Value type conversion failed: " + e.getMessage());
553
}
554
}
555
556
// Utility method for centralized error handling
557
public static void handlePlcException(Exception e) {
558
if (e instanceof PlcConnectionException) {
559
System.err.println("Connection Error: " + e.getMessage());
560
// Possibly retry connection
561
} else if (e instanceof PlcTimeoutException) {
562
System.err.println("Timeout Error: " + e.getMessage());
563
// Possibly retry operation
564
} else if (e instanceof PlcProtocolException) {
565
System.err.println("Protocol Error: " + e.getMessage());
566
// Log for debugging
567
} else if (e instanceof PlcUnsupportedOperationException) {
568
System.err.println("Operation not supported: " + e.getMessage());
569
// Use alternative approach
570
} else if (e instanceof PlcInvalidTagException) {
571
System.err.println("Invalid tag: " + e.getMessage());
572
// Validate tag addresses
573
} else if (e instanceof PlcIncompatibleDatatypeException) {
574
System.err.println("Data type error: " + e.getMessage());
575
// Check data type compatibility
576
} else if (e instanceof PlcException) {
577
System.err.println("PLC Error: " + e.getMessage());
578
// Generic PLC error handling
579
} else {
580
System.err.println("Unexpected error: " + e.getMessage());
581
e.printStackTrace();
582
}
583
}
584
```
585
586
## Error Handling Best Practices
587
588
### 1. Check Capabilities First
589
```java
590
PlcConnectionMetadata metadata = connection.getMetadata();
591
if (!metadata.isWriteSupported()) {
592
throw new PlcUnsupportedOperationException("Write operations not supported");
593
}
594
```
595
596
### 2. Handle Response Codes
597
```java
598
if (response.getResponseCode(tagName) == PlcResponseCode.OK) {
599
// Process successful response
600
} else {
601
// Handle specific error conditions
602
}
603
```
604
605
### 3. Use Try-With-Resources
606
```java
607
try (PlcConnection connection = driverManager.getConnection(url)) {
608
// Operations that may throw exceptions
609
} catch (PlcException e) {
610
// Handle PLC-specific errors
611
}
612
```
613
614
### 4. Validate Inputs
615
```java
616
Optional<PlcTag> tag = connection.parseTagAddress(tagAddress);
617
if (!tag.isPresent()) {
618
throw new PlcInvalidTagException("Invalid tag address: " + tagAddress);
619
}
620
```
621
622
### 5. Log Detailed Information
623
```java
624
catch (PlcException e) {
625
logger.error("PLC operation failed", e);
626
// Include context information in logs
627
}
628
```
629
630
The comprehensive exception hierarchy in Apache PLC4X provides fine-grained error handling capabilities, enabling robust industrial applications that can gracefully handle various failure scenarios common in industrial automation environments.