This document covers error handling strategies in cv4pve-api-java.
The Proxmox VE API can return different types of errors that need to be handled appropriately:
- HTTP Errors: Network-level errors (4xx, 5xx status codes)
- API Errors: Application-level errors from Proxmox VE
- Connection Errors: Network connectivity issues
- Client Errors: Problems with request formatting
HTTP errors are indicated by the HTTP status code. Always check isSuccessStatusCode():
var result = client.getNodes().get("pve1").getQemu().get(999).getStatus().current();
if (!result.isSuccessStatusCode()) {
switch (result.getStatusCode()) {
case 401:
System.err.println("Authentication failed - check credentials");
break;
case 403:
System.err.println("Permission denied - insufficient privileges");
break;
case 404:
System.err.println("Resource not found - check resource ID");
break;
case 429:
System.err.println("Rate limit exceeded - wait before retrying");
break;
case 500:
System.err.println("Internal server error - Proxmox VE issue");
break;
case 502:
System.err.println("Bad gateway - connection issue");
break;
case 503:
System.err.println("Service unavailable - Proxmox VE overloaded");
break;
default:
System.err.println("HTTP Error " + result.getStatusCode() + ": " + result.getReasonPhrase());
break;
}
}API errors come from Proxmox VE itself and are separate from HTTP errors:
var result = client.getNodes().get("pve1").getQemu().get(100)
.getConfig().updateVm(Map.of("memory", 999999999)); // Invalid memory value
if (result.responseInError()) {
System.err.println("API Error: " + result.getError());
// Example output: "Parameter verification failed. memory: value too large"
// Or: "VM 100 not running"
}Handle network-level exceptions:
try {
var client = new PveClient("invalid-host.com", 8006);
client.login("root", "password", "pam");
} catch (Exception e) {
System.err.println("Connection error: " + e.getMessage());
e.printStackTrace();
}Best practice for handling all types of errors:
public void createVm(String nodeName, int vmid, String name) {
try {
var result = client.getNodes().get(nodeName).getQemu().createVm(vmid, name, 512, 1);
if (result.isSuccessStatusCode()) {
if (!result.responseInError()) {
System.out.println("VM created successfully");
} else {
System.err.println("API Error: " + result.getError());
}
} else {
System.err.println("HTTP Error " + result.getStatusCode() + ": " + result.getReasonPhrase());
}
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
e.printStackTrace();
}
}Implement retry logic for transient failures:
public Result retryOperation(java.util.function.Supplier<Result> operation, int maxRetries) {
int retries = 0;
while (retries < maxRetries) {
var result = operation.get();
// If successful, return the result
if (result.isSuccessStatusCode() && !result.responseInError()) {
return result;
}
// Don't retry on certain error codes
int statusCode = result.getStatusCode();
if (statusCode == 400 || statusCode == 401 || statusCode == 403 || statusCode == 404) {
return result; // Don't retry for client errors
}
retries++;
if (retries < maxRetries) {
try {
Thread.sleep(1000 * retries); // Exponential backoff
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
return null;
}For production applications, use proper logging:
import java.util.logging.Logger;
import java.util.logging.Level;
private static final Logger logger = Logger.getLogger(ProxmoxManager.class.getName());
public void handleApiCall() {
var result = client.getCluster().getStatus().getStatus();
if (!result.isSuccessStatusCode()) {
logger.log(Level.SEVERE, "HTTP Error {0}: {1}",
new Object[]{result.getStatusCode(), result.getReasonPhrase()});
} else if (result.responseInError()) {
logger.severe("API Error: " + result.getError());
} else {
logger.info("API call successful");
}
}- Always check
isSuccessStatusCode()before accessing response data - Handle both HTTP and API errors separately
- Use appropriate logging for different error types
- Provide meaningful error messages to users
- Implement retry logic for transient failures
- Validate input parameters before making API calls
- Set appropriate timeouts to prevent hanging connections
- Clean up resources properly in error scenarios
For more details, see API Documentation.