Error Handling
Things don't always go as planned. This guide covers how to handle errors gracefully in the AD Device Manager SDK, including a comprehensive error code reference with recovery recommendations.
Error Handling Basics
The SDK uses CompletableFuture for asynchronous operations. Errors are handled using the .exceptionally() method rather than traditional try-catch blocks.
Basic Pattern
deviceAdapter.connect()
.thenAccept(unused -> {
// Success path
logger.info("Connected!");
})
.exceptionally(throwable -> {
// Error path
logger.error("Connection failed: {}", throwable.getMessage());
handleError(throwable);
return null; // Required to complete the future
});
Chained Operations
A single .exceptionally() at the end catches failures from any step in the chain:
deviceAdapter.connect()
.thenCompose(unused -> {
return deviceAdapter.registerResources("PrintResources", true, callback);
})
.thenCompose(unused -> {
return printerAdapter.print("Label.ngt", "DATA=test", 1);
})
.thenAccept(unused -> {
logger.info("All operations completed successfully");
})
.exceptionally(throwable -> {
// Catches errors from connect(), registerResources(), OR print()
logger.error("Operation failed: {}", throwable.getMessage());
return null;
});
Identifying Error Types
The SDK throws specific exception types that help you identify the cause:
.exceptionally(throwable -> {
Throwable cause = throwable.getCause();
if (cause instanceof BluetoothException) {
handleBluetoothError((BluetoothException) cause);
} else if (cause instanceof PrinterException) {
handlePrinterError((PrinterException) cause);
} else if (cause instanceof ResourceException) {
handleResourceError((ResourceException) cause);
} else if (cause instanceof ConnectionException) {
handleConnectionError((ConnectionException) cause);
} else {
handleGenericError(cause);
}
return null;
});
Best Practices
1. Always Handle Errors
Never leave .exceptionally() empty:
// ❌ Bad - errors silently swallowed
.exceptionally(e -> null);
// ✅ Good - errors logged and handled
.exceptionally(e -> {
logger.error("Operation failed", e);
showUserFriendlyError(e);
return null;
});
2. Provide User-Friendly Messages
Don't show raw error messages to users:
// ❌ Bad
showError(e.getMessage()); // "java.io.IOException: CONN_005"
// ✅ Good
showError("Unable to connect to the printer. Please try again.");
3. Log Full Error Details
Log complete information for debugging:
logger.error("Print operation failed: template={}, copies={}, errorCode={}",
templateName, copies, getErrorCode(e), e);
4. Offer Recovery Options
When possible, help users recover:
if (isPaperOut(error)) {
showDialog("Load paper and tap Retry", () -> retryPrint());
}
Next Steps
| Guide | What You'll Learn |
|---|---|
| Logging | Detailed error logging |
| Callbacks | Monitor for error conditions |
| Getting Started | Basic error handling patterns |