Saltar al contenido principal

Manejo de Errores

Esta guía te muestra cómo manejar errores correctamente cuando usas el SDK de Retorna.

Tipos de Errores

El SDK puede lanzar diferentes tipos de excepciones:

IllegalArgumentException

Lanzada cuando los parámetros proporcionados son inválidos:

try {
CreateOrderInput orderInput = new CreateOrderInput(
// ... parámetros inválidos
);
OrderResponse order = client.order.createPayoutOrder(orderInput);
} catch (IllegalArgumentException e) {
System.err.println("Error de validación: " + e.getMessage());
// Ejemplo: "clientId es requerido"
}

RuntimeException

Lanzada cuando hay errores de API (4xx, 5xx) o problemas de red:

try {
BalanceResponse balance = client.account.getBalance();
} catch (RuntimeException e) {
System.err.println("Error de API: " + e.getMessage());
// Ejemplo: "Error al obtener balance: 401 - Unauthorized"
}

Exception

Lanzada para otros errores generales (parsing, conexión, etc.):

try {
QuoteResponse quote = client.quotation.createQuote(quoteInput);
} catch (Exception e) {
System.err.println("Error general: " + e.getMessage());
e.printStackTrace();
}

Manejo de Errores Recomendado

Patrón Básico

try {
// Operación del SDK
BalanceResponse balance = client.account.getBalance();
System.out.println("Balance: " + balance.getTotalBalance());
} catch (IllegalArgumentException e) {
// Error de validación - datos inválidos
System.err.println("❌ Error de validación: " + e.getMessage());
// Tomar acción correctiva (mostrar mensaje al usuario, etc.)
} catch (RuntimeException e) {
// Error de API - problema con el servidor
System.err.println("❌ Error de API: " + e.getMessage());
// Reintentar, notificar, etc.
} catch (Exception e) {
// Error inesperado
System.err.println("❌ Error inesperado: " + e.getMessage());
e.printStackTrace();
// Logging, notificación, etc.
}

Manejo Específico por Operación

public class RetornaService {

public BalanceResponse getBalanceSafely(RetornaClient client) {
try {
return client.account.getBalance();
} catch (RuntimeException e) {
if (e.getMessage().contains("401") || e.getMessage().contains("403")) {
// Error de autenticación
throw new AuthenticationException("Credenciales inválidas", e);
} else if (e.getMessage().contains("500")) {
// Error del servidor
throw new ServerException("Error del servidor", e);
} else {
throw new RetornaException("Error desconocido", e);
}
}
}

public OrderResponse createOrderSafely(RetornaClient client, CreateOrderInput input) {
try {
return client.order.createPayoutOrder(input);
} catch (IllegalArgumentException e) {
// Error de validación
throw new ValidationException("Datos inválidos: " + e.getMessage(), e);
} catch (RuntimeException e) {
if (e.getMessage().contains("400")) {
// Bad Request
throw new BadRequestException("Solicitud inválida", e);
} else {
throw new RetornaException("Error al crear orden", e);
}
}
}
}

Códigos de Estado HTTP

El SDK puede recibir diferentes códigos de estado HTTP:

CódigoSignificadoAcción Recomendada
200, 201ÉxitoContinuar normalmente
400Bad RequestVerificar parámetros
401UnauthorizedVerificar credenciales
403ForbiddenVerificar permisos
404Not FoundRecurso no existe
500Internal Server ErrorReintentar más tarde
503Service UnavailableServicio no disponible

Ejemplo de Manejo por Código

public class ErrorHandler {
public static void handleApiError(RuntimeException e) {
String message = e.getMessage();

if (message.contains("401")) {
System.err.println("❌ Error de autenticación. Verifica tus credenciales.");
} else if (message.contains("403")) {
System.err.println("❌ Acceso denegado. Verifica tus permisos.");
} else if (message.contains("404")) {
System.err.println("❌ Recurso no encontrado.");
} else if (message.contains("400")) {
System.err.println("❌ Solicitud inválida. Verifica los parámetros.");
} else if (message.contains("500") || message.contains("503")) {
System.err.println("❌ Error del servidor. Intenta más tarde.");
} else {
System.err.println("❌ Error desconocido: " + message);
}
}
}

Reintentos Automáticos

El SDK maneja automáticamente algunos reintentos:

  • 401/403: El SDK intenta renovar el token y reintentar la solicitud
  • Errores de red: Puedes implementar tu propia lógica de reintentos

Implementar Reintentos Manuales

import java.util.concurrent.TimeUnit;

public class RetryExample {
public static BalanceResponse getBalanceWithRetry(
RetornaClient client, int maxRetries) {
int attempts = 0;

while (attempts < maxRetries) {
try {
return client.account.getBalance();
} catch (RuntimeException e) {
attempts++;

if (e.getMessage().contains("500") || e.getMessage().contains("503")) {
// Error del servidor - reintentar
if (attempts < maxRetries) {
System.out.println("Reintentando... (" + attempts + "/" + maxRetries + ")");
try {
TimeUnit.SECONDS.sleep(2 * attempts); // Backoff exponencial
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrumpido", ie);
}
continue;
}
}

// Otros errores o agotados los reintentos
throw e;
}
}

throw new RuntimeException("No se pudo obtener el balance después de " + maxRetries + " intentos");
}
}

Logging de Errores

Usa el sistema de logging del SDK para debuggear errores:

RetornaClient client = RetornaClient.create(
RetornaClientOptions.builder()
.environment(Environment.DEVELOP)
.loggingLevel(LoggingLevel.DEBUG) // Activar logging detallado
// ... otras configuraciones
.build()
);

Con LoggingLevel.DEBUG, verás:

  • Intentos de autenticación
  • Solicitudes HTTP
  • Respuestas de la API
  • Errores detallados

Errores Comunes y Soluciones

Error: "clientId es requerido"

Causa: No se proporcionó el clientId al crear el cliente.

Solución:

.clientId("tu-client-id") // Asegúrate de proporcionarlo

Error: "Error al obtener balance: 401"

Causa: Credenciales inválidas o token expirado.

Solución: Verifica tus credenciales. El SDK intentará renovar el token automáticamente.

Error: "Error de validación: ..."

Causa: Datos inválidos en la solicitud (ej: formato de documento incorrecto).

Solución: Verifica el formato de los datos según la plataforma de pago.

Error: "Formato de respuesta inesperado"

Causa: La API devolvió un formato inesperado.

Solución: Contacta al soporte o verifica la versión del SDK.

Mejores Prácticas

  1. Siempre maneja excepciones: No dejes que las excepciones se propaguen sin manejo
  2. Proporciona contexto: Incluye información útil en los mensajes de error
  3. Logging apropiado: Usa logging para debuggear, no para producción
  4. Reintentos inteligentes: Solo reintenta en errores recuperables (5xx)
  5. Validación temprana: Valida los datos antes de enviarlos al SDK

Ejemplo Completo

public class RobustErrorHandling {
public static void processPayment(RetornaClient client, CreateOrderInput input) {
try {
// Validar input antes de enviar
validateOrderInput(input);

// Crear orden
OrderResponse order = client.order.createPayoutOrder(input);
System.out.println("✅ Orden creada: " + order.getId());

} catch (IllegalArgumentException e) {
// Error de validación
System.err.println("❌ Error de validación: " + e.getMessage());
// Mostrar mensaje al usuario
showUserError("Por favor, verifica los datos ingresados.");

} catch (RuntimeException e) {
// Error de API
if (e.getMessage().contains("401") || e.getMessage().contains("403")) {
System.err.println("❌ Error de autenticación");
// Reautenticar o notificar
} else if (e.getMessage().contains("400")) {
System.err.println("❌ Solicitud inválida: " + e.getMessage());
// Mostrar error específico
} else {
System.err.println("❌ Error de API: " + e.getMessage());
// Reintentar o notificar
}

} catch (Exception e) {
// Error inesperado
System.err.println("❌ Error inesperado: " + e.getMessage());
e.printStackTrace();
// Logging y notificación
}
}

private static void validateOrderInput(CreateOrderInput input) {
if (input.getExternalId() == null || input.getExternalId().isEmpty()) {
throw new IllegalArgumentException("externalId es requerido");
}
// Más validaciones...
}

private static void showUserError(String message) {
// Implementar UI o logging
System.out.println("Error: " + message);
}
}

Siguiente Paso

Envía dinero
Desde Latinoamérica
ChileColombiaPerú
Desde Europa
EspañaItaliaFranciaAlemaniaPortugalPaíses Bajos
Recursos
Blog
Encuéntranos en redes
Para denuncias, por favor contactar al correo electrónico denuncias@retorna.app
Pertenecemos a la Unidad de Análisis Financiero (UAF).
Supervisados por
Registration number is C100000211.
Miembros de
Con el apoyo deCon el apoyo de
Copyright © Retorna Holding Spa 2024