El 73% de los desarrolladores junior falla su primer code review real. No por falta de conocimiento teórico — por patrones específicos que nadie les señaló durante el aprendizaje.
Acá están los 7 errores más comunes, con el código que los produce y la versión correcta.
Error 1 — No validar inputs
El error más frecuente y el más costoso en producción. Código que asume que los datos de entrada siempre vienen en el formato esperado.
# ❌ Sin validación
def calcular_descuento(precio, porcentaje):
return precio * (1 - porcentaje / 100)
# ✓ Con validación
def calcular_descuento(precio: float, porcentaje: float) -> float:
if precio < 0 or porcentaje < 0 or porcentaje > 100:
raise ValueError("Precio y porcentaje deben ser positivos")
return precio * (1 - porcentaje / 100)
Error 2 — Variables sin nombres descriptivos
El código con variables de una letra se escribe rápido y se lee lento. En un equipo, el tiempo de lectura importa más que el de escritura.
# ❌ Ilegible
def p(x, y):
r = []
for i in x:
if i > y:
r.append(i)
return r
# ✓ Auto-documenta
def filtrar_mayores(numeros: list, umbral: float) -> list:
return [n for n in numeros if n > umbral]
Error 3 — Atrapar excepciones en blanco
El except Exception as e: pass silencia errores reales. Es el equivalente a apagar la alarma de incendio en lugar de apagar el fuego.
# ❌ Silencia todo
try:
resultado = procesar_datos(datos)
except:
pass
# ✓ Manejo específico con logging
try:
resultado = procesar_datos(datos)
except ValueError as e:
logger.error(f"Datos inválidos: {e}")
raise
except ConnectionError as e:
logger.error(f"Error de conexión: {e}")
return None
Error 4 — Queries SQL sin parámetros
La vulnerabilidad de inyección SQL más clásica. Si el code reviewer lo ve, el PR muere ahí.
# ❌ Vulnerable a SQL injection
query = f"SELECT * FROM usuarios WHERE email = '{email}'"
cursor.execute(query)
# ✓ Con parámetros parametrizados
query = "SELECT * FROM usuarios WHERE email = %s"
cursor.execute(query, (email,))
Error 5 — Lógica duplicada en lugar de funciones
Copiar y pegar código que hace lo mismo en varios lugares. Cuando hay que cambiar algo, hay que cambiarlo en todos los lugares — y siempre se olvida uno.
# ❌ Duplicación
if usuario_tipo == "admin":
nombre = usuario.nombre.strip().lower()
email = usuario.email.strip().lower()
if usuario_tipo == "editor":
nombre = usuario.nombre.strip().lower()
email = usuario.email.strip().lower()
# ✓ Función reutilizable
def normalizar_usuario(usuario):
return {
"nombre": usuario.nombre.strip().lower(),
"email": usuario.email.strip().lower(),
}
Error 6 — No usar type hints
En equipos que usan mypy o Pyright, el código sin type hints genera warnings inmediatos. Más importante: las funciones sin tipos son más difíciles de usar correctamente.
# ❌ Sin tipos
def procesar_pedido(pedido, usuario, descuento):
...
# ✓ Con tipos
from typing import Optional
def procesar_pedido(
pedido: Pedido,
usuario: Usuario,
descuento: Optional[float] = None
) -> ResultadoPedido:
...
Error 7 — Lógica de negocio en el endpoint
Poner toda la lógica directamente en el handler de la API. Imposible de testear, difícil de modificar, imposible de reusar.
# ❌ Todo en el endpoint
@app.post("/pedidos")
def crear_pedido(datos: dict):
# 80 líneas de lógica de negocio mezclada con HTTP
...
# ✓ Separación de responsabilidades
@app.post("/pedidos")
def crear_pedido(datos: PedidoSchema):
resultado = servicio_pedidos.crear(datos)
return {"id": resultado.id}
Cómo entrenár estos patrones antes del primer trabajo
Conocer los errores no es suficiente — hay que desarrollar el hábito de evitarlos bajo presión. Eso requiere escribir código real que es evaluado por algo más que "funciona o no funciona".
En DAKI, las misiones están diseñadas para detectar exactamente estos patrones. DAKI analiza tu código y te señala el gap específico — no el error genérico, sino la lógica incorrecta tuya en particular.
El objetivo no es memorizár esta lista. Es que la próxima vez que escribas except: pass, algo en tu cabeza diga "no".