CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-google-api-client--google-api-client

The Google APIs Client Library for Java is a flexible, efficient, and powerful Java client library for accessing any HTTP-based API on the web, not just Google APIs.

Pending
Overview
Eval results
Files

json-error-handling.mddocs/

JSON Error Handling

Structured JSON error response parsing and exception handling with detailed error information from Google API responses.

Core Imports

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.googleapis.json.GoogleJsonErrorContainer;
import com.google.api.client.json.JsonFactory;

Exception Classes

GoogleJsonResponseException

HTTP response exception that includes structured JSON error details from Google APIs.

public class GoogleJsonResponseException extends HttpResponseException {
    public GoogleJsonError getDetails();
    
    public static GoogleJsonResponseException from(JsonFactory jsonFactory, HttpResponse response) 
        throws IOException;
    
    protected GoogleJsonResponseException(Builder builder, GoogleJsonError details);
    
    public static class Builder extends HttpResponseException.Builder {
        public GoogleJsonResponseException build();
        public Builder setDetails(GoogleJsonError details);
        public GoogleJsonError getDetails();
    }
}

Usage Example:

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.googleapis.json.GoogleJsonError;

try {
    // Execute Google API request
    MyApiResponse response = myApiClient.items().get(itemId).execute();
} catch (GoogleJsonResponseException e) {
    // Handle structured JSON error
    GoogleJsonError error = e.getDetails();
    
    System.err.println("API Error: " + e.getStatusCode() + " " + e.getStatusMessage());
    
    if (error != null) {
        System.err.println("Error Code: " + error.getCode());
        System.err.println("Error Message: " + error.getMessage());
        
        // Handle specific error cases
        switch (e.getStatusCode()) {
            case 400:
                handleBadRequest(error);
                break;
            case 401:
                handleUnauthorized(error);
                break;
            case 403:
                handleForbidden(error);
                break;
            case 404:
                handleNotFound(error);
                break;
            case 429:
                handleRateLimitExceeded(error);
                break;
            case 500:
                handleInternalServerError(error);
                break;
            default:
                handleGenericError(error);
        }
    }
} catch (IOException e) {
    // Handle general I/O errors
    System.err.println("Network error: " + e.getMessage());
}

Error Detail Classes

GoogleJsonError

Represents detailed error information from Google JSON API responses.

public final class GoogleJsonError extends GenericJson {
    public Integer getCode();
    public GoogleJsonError setCode(Integer code);
    
    public String getMessage();
    public GoogleJsonError setMessage(String message);
    
    public List<ErrorInfo> getErrors();
    public GoogleJsonError setErrors(List<ErrorInfo> errors);
    
    public static final class ErrorInfo extends GenericJson {
        public String getDomain();
        public ErrorInfo setDomain(String domain);
        
        public String getReason();
        public ErrorInfo setReason(String reason);
        
        public String getMessage();
        public ErrorInfo setMessage(String message);
        
        public String getLocation();
        public ErrorInfo setLocation(String location);
        
        public String getLocationType();
        public ErrorInfo setLocationType(String locationType);
        
        public String getExtendedHelp();
        public ErrorInfo setExtendedHelp(String extendedHelp);
        
        public String getSendReport();
        public ErrorInfo setSendReport(String sendReport);
    }
}

GoogleJsonErrorContainer

Container for Google JSON errors, used in batch operations and some API responses.

public class GoogleJsonErrorContainer extends GenericJson {
    public GoogleJsonError getError();
    public GoogleJsonErrorContainer setError(GoogleJsonError error);
}

Usage Example:

import com.google.api.client.googleapis.json.GoogleJsonError;

// Detailed error handling
private void handleDetailedError(GoogleJsonError error) {
    System.err.println("Main Error: " + error.getCode() + " - " + error.getMessage());
    
    // Process individual error details
    if (error.getErrors() != null) {
        for (GoogleJsonError.ErrorInfo errorInfo : error.getErrors()) {
            System.err.println("Error Detail:");
            System.err.println("  Domain: " + errorInfo.getDomain());
            System.err.println("  Reason: " + errorInfo.getReason());
            System.err.println("  Message: " + errorInfo.getMessage());
            
            if (errorInfo.getLocation() != null) {
                System.err.println("  Location: " + errorInfo.getLocation() + 
                                 " (" + errorInfo.getLocationType() + ")");
            }
            
            if (errorInfo.getExtendedHelp() != null) {
                System.err.println("  Help: " + errorInfo.getExtendedHelp());
            }
        }
    }
}

Error Handling Patterns

Specific Error Type Handlers

// Handle validation errors
private void handleBadRequest(GoogleJsonError error) {
    System.err.println("Validation Error: " + error.getMessage());
    
    if (error.getErrors() != null) {
        for (GoogleJsonError.ErrorInfo errorInfo : error.getErrors()) {
            if ("invalid".equals(errorInfo.getReason())) {
                System.err.println("Invalid field: " + errorInfo.getLocation());
            } else if ("required".equals(errorInfo.getReason())) {
                System.err.println("Missing required field: " + errorInfo.getLocation());
            }
        }
    }
}

// Handle authentication errors
private void handleUnauthorized(GoogleJsonError error) {
    System.err.println("Authentication failed: " + error.getMessage());
    // Trigger token refresh or re-authentication
    refreshAuthenticationToken();
}

// Handle permission errors
private void handleForbidden(GoogleJsonError error) {
    System.err.println("Access forbidden: " + error.getMessage());
    
    if (error.getErrors() != null) {
        for (GoogleJsonError.ErrorInfo errorInfo : error.getErrors()) {
            if ("insufficientPermissions".equals(errorInfo.getReason())) {
                System.err.println("Missing permission: " + errorInfo.getMessage());
            }
        }
    }
}

// Handle rate limiting
private void handleRateLimitExceeded(GoogleJsonError error) {
    System.err.println("Rate limit exceeded: " + error.getMessage());
    
    // Implement exponential backoff
    try {
        Thread.sleep(calculateRetryDelay());
        // Retry the request
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

Retry Logic with Error Analysis

public <T> T executeWithRetry(AbstractGoogleClientRequest<T> request, int maxRetries) 
    throws IOException {
    
    int attempt = 0;
    while (attempt < maxRetries) {
        try {
            return request.execute();
        } catch (GoogleJsonResponseException e) {
            attempt++;
            
            // Determine if error is retryable
            if (!isRetryableError(e) || attempt >= maxRetries) {
                throw e;
            }
            
            // Calculate delay based on error type
            long delay = calculateRetryDelay(e, attempt);
            
            try {
                Thread.sleep(delay);
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
                throw new IOException("Interrupted during retry", ie);
            }
        }
    }
    
    throw new IOException("Maximum retries exceeded");
}

private boolean isRetryableError(GoogleJsonResponseException e) {
    int statusCode = e.getStatusCode();
    
    // Retryable HTTP status codes
    if (statusCode == 429 || statusCode >= 500) {
        return true;
    }
    
    // Check for specific retryable error reasons
    GoogleJsonError error = e.getDetails();
    if (error != null && error.getErrors() != null) {
        for (GoogleJsonError.ErrorInfo errorInfo : error.getErrors()) {
            String reason = errorInfo.getReason();
            if ("rateLimitExceeded".equals(reason) || 
                "userRateLimitExceeded".equals(reason) ||
                "backendError".equals(reason)) {
                return true;
            }
        }
    }
    
    return false;
}

private long calculateRetryDelay(GoogleJsonResponseException e, int attempt) {
    // Base exponential backoff: 2^attempt * 1000ms
    long baseDelay = (long) Math.pow(2, attempt) * 1000;
    
    // Cap at 60 seconds
    baseDelay = Math.min(baseDelay, 60000);
    
    // Add jitter to prevent thundering herd
    long jitter = (long) (Math.random() * 1000);
    
    return baseDelay + jitter;
}

Error Logging and Monitoring

Structured Error Logging

import java.util.logging.Logger;
import java.util.logging.Level;

private static final Logger logger = Logger.getLogger(MyApiClient.class.getName());

private void logApiError(GoogleJsonResponseException e) {
    GoogleJsonError error = e.getDetails();
    
    // Create structured log entry
    StringBuilder logMessage = new StringBuilder();
    logMessage.append("Google API Error - ");
    logMessage.append("Status: ").append(e.getStatusCode()).append(" ");
    logMessage.append("Message: ").append(e.getStatusMessage()).append(" ");
    
    if (error != null) {
        logMessage.append("Code: ").append(error.getCode()).append(" ");
        logMessage.append("Details: ").append(error.getMessage());
        
        if (error.getErrors() != null) {
            logMessage.append(" Errors: [");
            for (GoogleJsonError.ErrorInfo errorInfo : error.getErrors()) {
                logMessage.append(errorInfo.getDomain())
                          .append("/")
                          .append(errorInfo.getReason())
                          .append(": ")
                          .append(errorInfo.getMessage())
                          .append("; ");
            }
            logMessage.append("]");
        }
    }
    
    logger.log(Level.WARNING, logMessage.toString(), e);
}

Error Metrics Collection

// Example error metrics collection
public class ApiErrorMetrics {
    private final Map<Integer, AtomicLong> statusCodeCounts = new ConcurrentHashMap<>();
    private final Map<String, AtomicLong> errorReasonCounts = new ConcurrentHashMap<>();
    
    public void recordError(GoogleJsonResponseException e) {
        // Count by status code
        statusCodeCounts.computeIfAbsent(e.getStatusCode(), k -> new AtomicLong(0))
                       .incrementAndGet();
        
        // Count by error reason
        GoogleJsonError error = e.getDetails();
        if (error != null && error.getErrors() != null) {
            for (GoogleJsonError.ErrorInfo errorInfo : error.getErrors()) {
                String reason = errorInfo.getReason();
                if (reason != null) {
                    errorReasonCounts.computeIfAbsent(reason, k -> new AtomicLong(0))
                                   .incrementAndGet();
                }
            }
        }
    }
    
    public void printMetrics() {
        System.out.println("API Error Metrics:");
        System.out.println("Status Codes:");
        statusCodeCounts.forEach((code, count) -> 
            System.out.println("  " + code + ": " + count.get()));
        
        System.out.println("Error Reasons:");
        errorReasonCounts.forEach((reason, count) -> 
            System.out.println("  " + reason + ": " + count.get()));
    }
}

Types

HttpResponseException

Base HTTP response exception class.

HttpResponse

HTTP response representation.

JsonFactory

JSON factory for parsing JSON content.

GenericJson

Base class for JSON data models.

IOException

Exception for I/O operations.

List<T>

Java list interface for collections.

Integer

Java integer wrapper class.

String

Java string class.

Logger

Java logging utility.

Map<K,V>

Java map interface for key-value collections.

AtomicLong

Thread-safe long counter for metrics.

Install with Tessl CLI

npx tessl i tessl/maven-com-google-api-client--google-api-client

docs

batch-operations.md

client-services.md

http-transport.md

index.md

json-error-handling.md

media-operations.md

oauth2-auth.md

utilities.md

tile.json