Regla
Detectar contradictorio o imposible lógica
Código que comprueba las después de que
ya violado violadas, o asume que
que son imposibles dado el flujo flujo.
Idiomas admitidos: 45+Introducción
La lógica contradictoria aparece cuando el código verifica condiciones que ya se sabe que son verdaderas o falsas basándose en el flujo de control anterior. Esto ocurre después de una refactorización, cuando la validación se reordena, o cuando los desarrolladores añaden comprobaciones defensivas sin comprender qué garantías ya existen. Una función que comprueba if (user !== null) después de llamar user.email tiene lógica contradictoria, la comprobación de nulos llega demasiado tarde. Estas imposibilidades lógicas indican problemas más profundos con la organización del código o una comprensión deficiente de lo que garantiza cada ruta de código.
Por qué es importante
Implicaciones de seguridad: Una validación falsa crea una peligrosa ilusión de seguridad. Cuando las comprobaciones de seguridad aparecen después de que los datos ya han sido utilizados, los atacantes pueden explotar la ventana antes de que se produzca la validación. El código que valida los permisos de usuario después de ejecutar operaciones privilegiadas no proporciona protección real, solo comentarios engañosos sobre seguridad.
Mantenibilidad del código: La lógica contradictoria sugiere que el código no coincide con el modelo mental del desarrollador. Alguien pensó que una condición necesitaba ser verificada pero la colocó mal, o el código fue refactorizado sin actualizar las comprobaciones relacionadas. Los futuros mantenedores no pueden confiar en que la validación exista donde se necesita, lo que les obliga a rastrear funciones completas para entender las garantías reales.
Indicadores de errores: Las condiciones imposibles rara vez existen de forma aislada. Señalan problemas más profundos como la falta de manejo de errores, suposiciones incorrectas sobre los contratos de funciones o refactorizaciones fallidas. Una comprobación que nunca puede ejecutarse a menudo significa que falta otra comprobación en algún otro lugar que debería haber evitado este estado.
Ejemplos de código
❌ No conforme:
function processOrder(order) {
if (!order) {
return { error: 'Order required' };
}
const total = order.items.reduce(
(sum, item) => sum + item.price,
0
);
if (order.items && order.items.length > 0) {
applyDiscount(order);
}
if (total < 0) {
throw new Error('Invalid total');
}
return { total, status: 'processed' };
}
Por qué es incorrecto: El código llama a order.items.reduce() que se bloquea si los elementos son null o no definido, luego comprueba si los elementos existen después. El total < 0 La comprobación también es contradictoria porque la función reduce siempre devuelve valores no negativos al sumar precios.
✅ Conforme:
function processOrder(order) {
if (!order || !order.items || order.items.length === 0) {
return { error: 'Valid order with items required' };
}
const hasInvalidPrice = order.items.some(
item => typeof item.price !== 'number' || item.price < 0
);
if (hasInvalidPrice) {
throw new Error('Invalid item prices');
}
const total = order.items.reduce(
(sum, item) => sum + item.price,
0
);
if (order.items.length >= 5) {
applyBulkDiscount(order);
}
return { total, status: 'processed' };
}
Por qué esto es importante: Toda la validación ocurre antes de usar los datos, las comprobaciones se realizan en orden lógico y las condiciones reflejan los requisitos reales. La función valida las entradas de antemano, luego procesa los datos válidos sin comprobaciones redundantes o contradictorias.
Conclusión
Coloca la validación antes de usar los datos, no después. Revisa las condiciones que parecen defensivas pero que aparecen después de que los datos ya han sido accedidos o modificados. Al refactorizar, actualiza o elimina la validación relacionada para mantener la coherencia lógica en toda la función.
.avif)
