Saltar al contenido

Lección 6 de 17 · Lectura y práctica

Validación y manejo de errores en Server Actions

Concepto claveLa validación y manejo de errores en Server Actions es el proceso de asegurar que los datos que llegan a tu servidor sean correctos y de responder adecuadamente cuando algo falla. Imagina que eres un recepcionista.

Del concepto a la práctica

Taller de esta lección

Validar no significa solo comprobar que exista un campo: también implica longitud, formato y reglas del dominio. Para una etiqueta de artículo, aceptaremos entre 3 y 12 caracteres y eliminaremos espacios al inicio o al final antes de comprobar la longitud.

Ejemplo resuelto

ts
'use server'
export async function addTag(formData: FormData) {
  const value = formData.get('tag')
  if (typeof value !== 'string') return { ok: false, error: 'Se requiere texto' }
  const raw = value
  const tag = raw.trim()
  if (tag.length < 3 || tag.length > 12) return { ok: false, error: 'La etiqueta debe tener 3–12 caracteres' }
  return { ok: true, tag }
}

" SSR " produce SSR; "JS" produce error.

Pruébalo

  1. Envía App y conserva el valor normalizado.

  2. Envía JS y registra el error.

  3. Envía una cadena de 13 caracteres.

  4. Muestra el mensaje sin revelar detalles internos.

Comprueba tu resultado

Error frecuente: lanzar el error original directamente a la interfaz. Corrígelo convirtiéndolo en un resultado controlado. Resultado esperado: App devuelve ok: true, tag: App; JS y la cadena de 13 caracteres devuelven ok: false con el mismo mensaje de regla.

Observa el error en pantalla

Adapta el formulario con useActionState de la lección anterior y muestra el error en un elemento asociado al campo, con aria-live. Prueba exactamente App, JS, ABCDEFGHIJKLM y dos espacios: éxito, error, error y error. La normalización de SSR con espacios produce SSR, no un rechazo. Para este contrato cuenta unidades UTF-16 con length; si el producto exige caracteres visuales, define y prueba esa regla aparte. Una excepción inesperada se registra en servidor con un ID de seguimiento y una respuesta pública controlada.

Servidor que produce HTML y navegador que lo muestra y gestiona la interacción; claves sensibles permanecen en el servidor.
CursaloMapa de práctica
Dónde se ejecuta cada parte

El servidor puede obtener datos y producir el HTML inicial. El navegador muestra el resultado y ejecuta las interacciones que necesitan estado local. Mantén las claves sensibles en el servidor y define qué parte se ejecuta en cada entorno.

Ver la infografía en tamaño completo ↗
Fuentes para profundizar

Concepto clave

La validación y manejo de errores en Server Actions es el proceso de asegurar que los datos que llegan a tu servidor sean correctos y de responder adecuadamente cuando algo falla. Imagina que eres un recepcionista en un hotel: primero verificas que la reserva del cliente tenga todos los datos necesarios (validación), y si falta algo, le explicas claramente qué necesita corregir (manejo de errores), en lugar de simplemente rechazarlo sin más.

En Next.js 15, con Server Components y Streaming SSR, este proceso es crucial porque las acciones del servidor se ejecutan directamente en el entorno del servidor, sin pasar por una API tradicional. Esto significa que debes validar tanto en el cliente (para experiencia de usuario) como en el servidor (para seguridad), y manejar errores de forma que el usuario entienda qué pasó, especialmente cuando usas streaming, donde la interfaz puede actualizarse progresivamente.

Cómo funciona en la práctica

Vamos a crear una Server Action para registrar un usuario, con validación y manejo de errores paso a paso. Primero, define la acción en un archivo separado, por ejemplo actions/register.ts:

// actions/register.ts
'use server';

import { z } from 'zod';

const userSchema = z.object({
  email: z.string().email('Email inválido'),
  password: z.string().min(8, 'La contraseña debe tener al menos 8 caracteres'),
  name: z.string().min(2, 'El nombre debe tener al menos 2 caracteres'),
});

export async function registerUser(formData: FormData) {
  try {
    const rawData = {
      email: formData.get('email'),
      password: formData.get('password'),
      name: formData.get('name'),
    };
    
    // Validación con Zod
    const validatedData = userSchema.parse(rawData);
    
    // Lógica de negocio, ej., guardar en base de datos
    // Simulamos un error de base de datos
    const dbResult = await saveToDatabase(validatedData);
    if (!dbResult.success) {
      throw new Error('Error al guardar en la base de datos');
    }
    
    return { success: true, message: 'Usuario registrado exitosamente' };
  } catch (error) {
    if (error instanceof z.ZodError) {
      return { 
        success: false, 
        errors: error.errors.map(e => ({ field: e.path[0], message: e.message }))
      };
    }
    return { 
      success: false, 
      message: error instanceof Error ? error.message : 'Error desconocido'
    };
  }
}

async function saveToDatabase(data: any) {
  // Simulación de operación de base de datos
  return Math.random() > 0.5 ? { success: true } : { success: false };
}

Luego, en tu componente, usa useActionState (en Next.js 15) para manejar el estado de la acción y mostrar errores:

// app/register/page.tsx
'use client';

import { useActionState } from 'react';
import { registerUser } from '@/actions/register';

export default function RegisterPage() {
  const [state, action, isPending] = useActionState(registerUser, null);
  
  return (
    
  );
}

Caso de estudio

Imagina que estás construyendo una app de e-commerce con Next.js 15. Tienes una Server Action para procesar pedidos. Los datos del pedido incluyen:

CampoTipoValidación
productIdstringDebe ser un UUID válido
quantitynumberDebe ser mayor a 0 y menor a 100
shippingAddressstringDebe tener al menos 10 caracteres

Usa Zod para definir el esquema y maneja errores específicos: si el producto no existe, devuelve "Producto no encontrado"; si el stock es insuficiente, devuelve "Stock insuficiente". Con Streaming SSR, puedes mostrar un mensaje de "Procesando pedido..." mientras se valida y luego actualizar a éxito o error sin recargar la página.

En producción, siempre valida en el servidor, incluso si ya lo hiciste en el cliente, para prevenir ataques de manipulación de datos.

Errores comunes

  • Validar solo en el cliente: Los usuarios pueden deshabilitar JavaScript o manipular las solicitudes. Siempre valida también en el servidor con una librería como Zod o Yup.
  • Mensajes de error genéricos: Evita mensajes como "Algo salió mal". En su lugar, proporciona detalles específicos, como "El email ya está registrado" o "La contraseña es demasiado corta".
  • No manejar errores asíncronos: Si tu Server Action llama a una API externa o base de datos, envuelve esas llamadas en try-catch para capturar y manejar errores de red o de servidor.
  • Ignorar el estado de carga: Con Server Actions y Streaming, usa useActionState o similar para mostrar indicadores de carga (como isPending), mejorando la experiencia de usuario.
  • Exponer detalles internos en errores: No devuelvas mensajes de error que revelen información sensible, como detalles de la base de datos. En su lugar, registra esos errores internamente y muestra un mensaje amigable al usuario.

Checklist de dominio

  1. ¿Puedes definir un esquema de validación con Zod para una Server Action que incluya al menos tres campos con reglas diferentes?
  2. ¿Sabes usar useActionState en un componente cliente para manejar el estado de una Server Action, incluyendo errores y carga?
  3. ¿Puedes diferenciar entre errores de validación (ej., datos inválidos) y errores de negocio (ej., stock insuficiente) y manejarlos por separado?
  4. ¿Entiendes cómo el Streaming SSR afecta la visualización de errores y mensajes de éxito en tiempo real?
  5. ¿Has implementado validación tanto en cliente (para feedback inmediato) como en servidor (para seguridad) en un proyecto real?
  6. ¿Puedes escribir pruebas unitarias para una Server Action que verifiquen los casos de éxito y error?
  7. ¿Sabes configurar un middleware de logging para registrar errores de Server Actions sin afectar la respuesta al usuario?

Implementa una Server Action con validación y manejo de errores para un formulario de contacto

En este ejercicio, crearás una Server Action en Next.js 15 para manejar un formulario de contacto, con validación robusta y manejo de errores apropiado. Sigue estos pasos:

  1. Crea un nuevo proyecto Next.js 15 o usa uno existente. Asegúrate de tener el App Router habilitado.
  2. En la carpeta app/contact, crea un archivo page.tsx que sea un componente cliente. Este debe contener un formulario con los siguientes campos:
    • Nombre (texto, requerido, mínimo 2 caracteres)
    • Email (email, requerido, formato válido)
    • Mensaje (textarea, requerido, mínimo 10 caracteres)
  3. En la carpeta actions, crea un archivo contact.ts. Define una Server Action llamada submitContactForm que:
    • Use Zod para validar los datos del formulario según las reglas anteriores.
    • Simule el envío del mensaje (puedes usar un setTimeout para simular una operación asíncrona).
    • Maneje errores: si la validación falla, devuelve errores específicos por campo; si hay un error en el envío simulado, devuelve un mensaje genérico pero informativo.
    • Devuelva un objeto con success y message o errors.
  4. En el componente page.tsx, importa la Server Action y usa useActionState para manejar el estado. Muestra:
    • Mensajes de error debajo de cada campo si la validación falla.
    • Un mensaje general de éxito o error después del envío.
    • Un botón que se deshabilite (disabled) mientras la acción está en progreso (isPending).
  5. Prueba el formulario: envía con datos válidos, con datos inválidos, y simula un error en el envío (por ejemplo, lanzando un error aleatorio en la acción). Verifica que los mensajes se muestren correctamente.
Pistas
  • Usa z.string().email() de Zod para validar el campo email, y z.string().min() para los otros campos.
  • En useActionState, el primer argumento es la Server Action, y el estado inicial puede ser null. Accede a los errores con state?.errors.
  • Para simular un error en el envío, puedes agregar if (Math.random() > 0.5) throw new Error('Error de red simulado'); en la acción después de la validación.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Next.js 15: Aplicaciones Full-Stack con Server Components y Streaming SSR

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.