Atlasingeniería

Code review en la prácticaRobustez donde el usuario es impredecibleTema 1

Nulos, listas vacías y respuestas que no llegan

Tres estados que el código suele tratar como uno solo: no hay datos, todavía no llegaron y falló la llamada. Mostrar lo mismo en los tres casos es la causa más común de una pantalla que parece rota sin estarlo.

Una lista vacía y una llamada que falló se ven igual en la pantalla: no hay nada. Pero significan cosas opuestas, y el usuario hace cosas distintas en cada caso: si no tiene pedidos, entiende; si falló la red, quiere reintentar.

Es el comentario de review que más aparece sobre pantallas: «¿y si el servicio falla, qué se ve?».

Los cuatro estados de una pantalla con datos

EstadoQué debería verseQué suele verse
CargandoUn esqueleto o indicadorLa pantalla vacía, que parece «no hay nada»
Con datosLos datosBien
Vacío legítimoUn mensaje que explique y ofrezca la acción siguienteUna lista en blanco sin contexto
ErrorQué pasó y un botón de reintentarLo mismo que el vacío, o una pantalla en blanco
Colapsar vacío y error en el mismo camino es lo que produce reclamos del tipo «se me borraron los datos».

Hay un quinto caso que aparece en productos con sesión: sin permiso. Mostrarlo como vacío hace que el usuario crea que perdió algo, cuando en realidad necesita otro rol.

El nulo que llega igual

La otra mitad del problema es que el dato llega, pero incompleto. En una aplicación con datos de varios servicios, la garantía de que un campo siempre viene es más débil de lo que el tipo declara.

Dónde entra un nulo que el tipo decía que no podía entrar

  1. La respuesta del servicio, si el tipo se escribió a mano y el contrato cambió.
  2. Lo que se parsea: datos guardados por una versión anterior de la aplicación, con otra forma.
  3. Los parámetros de la URL, que los edita cualquiera.
  4. Un cálculo propio que devuelve indefinido en un caso raro y nadie lo previó.

La respuesta que no llega nunca

El caso menos contemplado no es el error sino el silencio: la llamada que queda esperando. Sin un tiempo límite, la pantalla se queda cargando para siempre y el usuario recarga.

Antes de seguir, predecí

Una pantalla necesita datos de tres servicios y uno de ellos es opcional. ¿Cómo conviene resolverlo?

Y un detalle que aparece en reviews de pantallas que se actualizan: si se dispara una llamada nueva antes de que vuelva la anterior, hay que cancelar la vieja. Si no, la respuesta que llega segunda puede ser la más vieja y pisar los datos correctos.

Degradar en vez de romper

La conclusión práctica no es “capturar todos los errores” sino decidir, por cada sección, si su falla arruina la pantalla o sólo esa sección.

Cómo se decide

  1. Lo esencial falla ruidoso. Si sin ese dato la pantalla miente —un precio, un saldo—, mejor un error visible que un número inventado.
  2. Lo accesorio desaparece. Un cartel de recomendaciones que no cargó no tiene que romper el resto; se oculta y se registra.
  3. El error se registra siempre, aunque el usuario no vea nada. Una sección que se oculta en silencio y nadie mide es una funcionalidad que puede estar caída hace semanas.
  4. El reintento es del usuario, no automático infinito. Reintentar sin límite contra un servicio caído lo empeora; un botón devuelve el control y no genera carga.
Más a fondo · nivel seniorEl estado vacío es una oportunidad de producto

El vacío legítimo suele tratarse como un caso de borde técnico y en realidad es la primera pantalla que ve un usuario nuevo. Un mensaje que explica qué va a aparecer ahí y ofrece la acción para empezar convierte mucho mejor que una lista en blanco. Es de los pocos casos donde el comentario de review lo hace producto y no ingeniería.

Los cuatro estados en un diff

src/orders/order-list.tsx+8−2

Hay 4 problemas en este cambio. Tocá la línea donde creas que está.

@@ -8,10 +8,18 @@ export const OrderList = () => {
8
8
9
10
11
12
913
1014
11
15
16
17
1218
1319

Cargando, con datos, vacío y con error. Este componente resuelve dos, y los otros dos se ven iguales.

Los cuatro estados, siempre

Cierre

Autoevaluación

¿Lo entendiste?

¿Por qué es problemático mostrar lo mismo cuando la lista está vacía y cuando la llamada falló?
Una sección accesoria falla y se oculta. ¿Qué falta para que eso sea correcto?