Regra
Detectar contraditório ou impossível lógica
Código que verifica condições após elas
já violadas violadas, ou presume que
que são impossíveis dado o fluxo fluxo.
Idiomas suportados: 45+Introdução
Lógica contraditória aparece quando o código verifica condições que já são conhecidas como verdadeiras ou falsas com base em um fluxo de controle anterior. Isso acontece após refatorações, quando a validação é reordenada, ou quando desenvolvedores adicionam verificações defensivas sem entender quais garantias já existem. Uma função que verifica if (user !== null) após chamar user.email possui lógica contraditória, a verificação de nulo chega tarde demais. Essas impossibilidades lógicas indicam problemas mais profundos com a organização do código ou falta de compreensão do que cada caminho de código garante.
Por que isso importa
Implicações de segurança: A validação falsa cria uma perigosa ilusão de segurança. Quando as verificações de segurança aparecem depois que os dados já foram usados, atacantes podem explorar a janela antes que a validação ocorra. O código que valida permissões de usuário após executar operações privilegiadas não oferece proteção real, apenas comentários enganosos sobre segurança.
Manutenibilidade do código: Lógica contraditória sugere que o código não corresponde ao modelo mental do desenvolvedor. Alguém pensou que uma condição precisava ser verificada, mas a colocou no lugar errado, ou o código foi refatorado sem atualizar as verificações relacionadas. Futuros mantenedores não podem confiar que a validação existe onde é necessária, forçando-os a rastrear funções inteiras para entender as garantias reais.
Indicadores de bug: Condições impossíveis raramente existem isoladamente. Elas sinalizam problemas mais profundos, como falta de tratamento de erros, suposições incorretas sobre contratos de função ou refatoração falha. Uma verificação que nunca pode ser executada frequentemente significa que outra verificação está faltando em algum outro lugar que deveria ter prevenido este estado.
Exemplos de código
❌ Não-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 que está errado: O código chama order.items.reduce() que falha se os itens forem nulo ou indefinido, então verifica se os itens existem depois. O total < 0 a verificação também é contraditória porque a função reduce sempre retorna valores não negativos ao somar preços.
✅ Compatível:
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 que isso importa: Toda a validação ocorre antes de usar os dados, as verificações acontecem em ordem lógica e as condições refletem os requisitos reais. A função valida as entradas antecipadamente e, em seguida, processa dados válidos sem verificações redundantes ou contraditórias.
Conclusão
Coloque a validação antes de usar os dados, não depois. Revise as condições que parecem defensivas, mas aparecem depois que os dados já foram acessados ou modificados. Ao refatorar, atualize ou remova a validação relacionada para manter a consistência lógica em toda a função.
.avif)
