Desarrollo web

El 404 con estilo, el 500 cazado y el primer esbozo del migrador

Páginas de error propias, una auditoría que convierte 500 en 404, y el primer esbozo del migrador de WordPress a Payload con 64 tests.

El 404 con estilo, el 500 cazado y el primer esbozo del migrador

Un 404 que no parezca error

Hasta ahora, si abrías una URL que no existía, Next.js te servía su página gris de siempre. Esta semana hemos hecho la nuestra. Dos piezas: un not-found.tsx en la raíz, para URLs desconocidas tipo /xyz, y otro dentro del grupo (frontend), para los notFound() que lanzan las fichas cuando no encuentran contenido.

Y un error.tsx para los errores de verdad: componente de cliente, role=alert, botón para reintentar. Al usuario no le enseñamos el mensaje técnico; en la consola sí queda registrado.

Lo curioso: el primer deploy sirvió el 404 de la raíz con el marcado correcto pero sin ni una hoja de estilos. El layout con los CSS vive en el grupo (frontend), y el not-found de la raíz cuelga directamente de app/layout. Next no propaga los imports de CSS hacia arriba en el árbol de rutas. Solución poco glamurosa y correcta: re-importar tokens.css, base.css y ui.css en el propio fichero. El bundle del 404 (49KB) ahora lleva las clases .notfound, y el de la home sigue limpio — eso demuestra que el import queda cerrado en el chunk del 404.

La caza del 500

La auditoría de las fichas cazó uno gordo: /consells/incorrecta/com-reduir... — una categoría que no existe — devolvía un 500. Postgres rechazaba el valor fuera del enum (22P02) y la excepción subía hasta la página. Ahora lib/format.ts exporta CONSELL_CATEGORIES y si la categoría no está en la lista, se corta con notFound() antes de tocar la base de datos. La URL sucia da 404, que es lo que toca.

Segundo intento del mismo día: filtrar por _status = 'published'. También 500 — Payload no deja consultar _status. Y sobra: el acceso onlyPublicat ya filtra los borradores. Lo hemos dejado comentado en las seis páginas para que nadie recaiga.

Detalles de las listas

La auditoría de las listas (spec 03j) dejó cuatro arreglos:

  • listingHref no reiniciaba page=1 al cambiar de filtro.
  • Las páginas 2+ con filtro activo se marcaban como indexables; ahora son noindex. Solo la página 1 sin filtros se puede indexar.
  • El mapa de comarcas del hero de /agenda no existía: tres enlaces con el color de cada comarca.
  • Los días de la agenda ahora muestran el día de la semana en rojo: DL., DT., DC…

Y todas las listas pasan de force-dynamic a revalidate = 3600, como pide la especificación. El 404 también debe ser force-dynamic; si no, Next lo prerenderiza estático con las landings y sirve su “404” por defecto en lugar del nuestro.

Y ya tenemos el migrador esbozado

Fase 3 a la vista. Hemos creado scripts/migrate-wp/wp_to_payload.py: el mapeo de cada post_type de WordPress a su colección de Payload, las reglas de descarte (D1-D4, con detección de Elementor) y las listas de enums por colección. Con tests: 64 comprobaciones, todas en verde.

El siguiente paso es la importación piloto de una comarca. De eso hablamos mañana.