Skip to main content

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

GuideWhat You'll Learn
LoggingDetailed error logging
CallbacksMonitor for error conditions
Getting StartedBasic error handling patterns