SLIDE 1 / 7

1. The Throwable Family Tree

All anomalies in Java descend from Throwable. The Error branch models catastrophic JVM failures (do not catch). The Exception branch splits into Checked (compiler-enforced) and RuntimeException (unchecked logic bugs).

Throwable Error (Fatal JVM) OutOfMemoryError StackOverflowError Exception (Recuperables) Aplicación puede responder Checked Exception IOException, SQLException throws o try/catch RuntimeException NullPointerException, Index... Unchecked (Bugs lógicos)
Exception Filter
Category: Checked vs Unchecked
Compiler Requirement: Exige declarar o atrapar
// Checked: Obligación sintáctica
public void leerArchivo() throws IOException {
  new FileInputStream("datos.csv");
}

2. Anatomy of an Exception in Memory

An exception is not a simple flag: it is a FULL OBJECT allocated in the Heap. Instantiating it takes an exact snapshot of the Call Stack (StackTrace), a descriptive message, and an optional root cause.

Objeto en Heap: SaldoInsuficienteException @0x3E80 String message: "Saldo insuficiente: requerido $500.00, disponible $120.00" StackTraceElement[] stackTrace: at CuentaBancaria.debitar(CuentaBancaria.java:45) at CajeroService.retirar(CajeroService.java:22) Throwable cause: null (Error raíz primario)
Diagnostic Fields
getMessage() method: Explicación para humanos / logs
Cost of new Exception: fillInStackTrace() recorre la pila
Best Practice: No usar excepciones para control de flujo
if (saldo < monto) {
  throw new SaldoInsuficienteException(
    "Saldo insuficiente: requerido " + monto
  );
}

3. Call Stack Unwinding Simulator

When an exception is thrown and the method has no catch block, its execution frame is destroyed and the exception propagates to the caller, bubbling up until caught or terminating the thread.

Call Stack (Hilos Activos) main() [try-catch] procesarOrden() validarStock() consultarBD() ⚡ Paso 1: Error en consultarBD() SQLException detonada Sin bloque catch local Acción de la JVM: Destruir frame consultarBD() Propaga a: validarStock()
Propagation Stepper
Current Frame: consultarBD()
Matching catch block?: NO -> Frame destruido
try {
  servicio.procesarOrden();
} catch (SQLException e) {
  // main() captura el error y rescata el hilo
  LOGGER.error("Fallo en BD: " + e.getMessage());
}

4. State Machine: try-catch-finally

The finally block is GUARANTEED to execute: when try finishes cleanly, when an exception is caught, and even when an uncaught exception keeps bubbling up.

Bloque try Código riesgoso Bloque catch Manejo de error Bloque finally ¡SIEMPRE corre! Ruta Activa: Camino Feliz (Sin Excepción) 1. Ejecuta try -> 2. Saltea catch -> 3. Ejecuta finally -> 4. Sigue El bloque finally liberó recursos de forma segura.
Route Selector
finally Execution: Garantizada al 100%
return inside try: finally corre antes de salir
try {
  // operacion()
} catch (Exception e) {
  // manejo()
} finally {
  conexion.cerrar(); // Siempre garantizado
}

5. try-with-resources and AutoCloseable

Since Java 7, any class implementing AutoCloseable can be opened within try parentheses. The JVM guarantees calling close() automatically upon exiting the block, even when exceptions occur.

✕ Código Legado (Pre-Java 7) Reader r = null; try { r = new Reader(); } finally { if (r != null) { try { r.close(); } catch (IOException e) {} } } // 25 líneas propensas a leaks ✓ try-with-resources (Moderno) try (Reader r = new Reader()) { r.read(); } // close() automático aquí AutoCloseable Limpio, seguro y sin fugas de socket/file
AutoCloseable Contract
Implicit Close: r.close() antes de catch/finally
Suppressed Exceptions: e.getSuppressed()
// Varios recursos separados por punto y coma
try (var in = new FileInputStream(f1);
     var out = new FileOutputStream(f2)) {
  in.transferTo(out);
}

6. Custom Exceptions and Chained Causes

Translate low-level technical infrastructure faults into domain concepts using the cause constructor: throw new PaymentFailedException("Charge failed", rootCause). This retains the full trace without leaking raw internals.

PagoFallidoException (Dominio) "Error al cobrar orden ID 1042" cause: SocketTimeoutException → SocketTimeoutException (Infra) "Read timed out at port 443" Causa física original Consola / Logs en Producción: com.tienda.PagoFallidoException: Error al cobrar orden ID 1042 Caused by: java.net.SocketTimeoutException: Read timed out
Domain Best Practices
Cause Constructor: super(mensaje, causa);
Trace Preservation: No se pierde el origen real
public class PagoException extends Exception {
  public PagoException(String msg, Throwable cause) {
    super(msg, cause); // Encadenamiento
  }
}

7. 4 Anti-Patterns to Avoid

Mistakes that ruin observability and cause silent disasters in production. Learn to detect and avoid them.

1. El Tragador de Errores catch (Exception e) { } Bomba de tiempo: silencia bugs 2. Atrapador Indiscriminado catch (Throwable t) Atrapa OutOfMemoryError sin querer 3. Loguear y Relanzar log.error(e); throw e; Duplica líneas y satura el log 4. Control de Flujo con Exception while(true) { try { ... } } Lento; romper pila es costoso
Golden Rule
Responsibility: Atrapá solo si podés recuperarte
If cannot recover: Dejá que suba o encapsulá
// O lo manejás de verdad, o lo dejás subir
try {
  debitar();
} catch (SaldoInsuficienteException e) {
  notificarCliente(e.getMessage()); // Acción concreta
}