Aikido

Como identificar e remover código morto inalcançável

Legibilidade

Regra
Remover inacessível morto código
Inacessível código é confuso, não testável,
e deve ser removido.

Idiomas suportados: 45+

Introdução

Código inalcançável sinaliza lógica quebrada em sua base de código. Código após retornar ou throw declarações foi escrita para ser executada, mas nunca roda. Condições que são sempre falsas ocultam validações ou tratamentos de erro que nunca são acionados. Ramificações que a lógica nunca alcança devido ao fluxo de controle contêm funcionalidades que não podem ser executadas. Ao encontrar código inalcançável, você encontrou um bug onde seu código não está fazendo o que deveria.

Por que isso importa

Vulnerabilidades de segurança: Verificações de segurança inalcançáveis não protegem sua aplicação. Se autenticação, autorização ou validação de entrada aparecerem após um(a) retornar declaração, seu código parece seguro, mas não é. Atacantes podem explorar funções que parecem ter medidas de segurança, mas na verdade as contornam. A revisão de código pode não detectar essas vulnerabilidades porque a lógica de segurança existe na base de código, mas nunca é executada.

Bugs de lógica em produção: Código morto significa que sua função não está implementando a lógica que você pensa. Validações que nunca são executadas permitem a passagem de dados inválidos. Tratamento de erros inatingível significa que os erros se propagam sem serem capturados. Regras de negócio que são ignoradas produzem resultados incorretos. O código parece correto, mas se comporta de forma diferente do pretendido.Lacunas nos testes: Código inatingível não pode ser testado. Se sua suíte de testes passa apesar de um código crítico ser inatingível, significa que você não tem testes cobrindo esses caminhos. Código inatingível revela lacunas na sua cobertura de testes, onde existe lógica importante, mas sem testes que verifiquem sua execução.

Impacto no tamanho do Bundle: Código inalcançável ainda é entregue aos usuários como peso morto em seu bundle JavaScript. Os usuários baixam e analisam código que nunca é executado, mas isso é secundário aos bugs de lógica que o código morto indica.

Exemplos de código

❌ Não-conforme:

function transferFunds(fromAccount, toAccount, amount) {
    if (!fromAccount || !toAccount) {
        return { success: false, error: 'Invalid accounts' };
    }

    if (amount <= 0) {
        return { success: false, error: 'Invalid amount' };
        logSuspiciousActivity(fromAccount, amount);
    }

    const balance = getBalance(fromAccount);
    if (balance >= amount) {
        deductFunds(fromAccount, amount);
        addFunds(toAccount, amount);
        return { success: true };
    }

    return { success: false, error: 'Insufficient funds' };

    // Check for fraud patterns
    if (isHighRiskTransaction(fromAccount, toAccount, amount)) {
        notifyFraudTeam(fromAccount, toAccount, amount);
        return { success: false, error: 'Transaction blocked' };
    }
}

Por que está errado: A lógica de detecção de fraude nunca é executada porque a função retorna antes de alcançá-la. O registro de atividade suspeita após a verificação do valor também nunca é executado. Esta função parece ter medidas de segurança, mas na verdade processa todas as transferências sem verificações de fraude.

✅ Compatível:

function transferFunds(fromAccount, toAccount, amount) {
    if (!fromAccount || !toAccount) {
        return { success: false, error: 'Invalid accounts' };
    }

    if (amount <= 0) {
        logSuspiciousActivity(fromAccount, amount);
        return { success: false, error: 'Invalid amount' };
    }

    if (isHighRiskTransaction(fromAccount, toAccount, amount)) {
        notifyFraudTeam(fromAccount, toAccount, amount);
        return { success: false, error: 'Transaction blocked' };
    }

    const balance = getBalance(fromAccount);
    if (balance >= amount) {
        deductFunds(fromAccount, amount);
        addFunds(toAccount, amount);
        return { success: true };
    }

    return { success: false, error: 'Insufficient funds' };
}

Por que isso importa: Todas as verificações de segurança são executadas antes de processar a transferência. A detecção de fraude é executada em cada transação. Atividades suspeitas são registradas. A função implementa a lógica de segurança que aparenta ter.

Conclusão

Código inalcançável indica falhas na sua lógica onde a funcionalidade pretendida nunca é executada. Encontre-o com ferramentas de análise estática em seu pipeline de CI e trate-o como um problema crítico, não apenas como uma limpeza de código. Ao descobrir código inalcançável, investigue por que ele existe e qual lógica deveria ser executada, mas não é.

FAQs

Dúvidas?

Como identificar código inalcançável em grandes bases de código?

Ferramentas de análise estática podem detectar casos óbvios, como código após instruções return ou throw. Para casos mais complexos, use ferramentas de cobertura de código durante os testes. O código que mostra cobertura zero em todas as execuções de teste pode ser inalcançável. Revise cada caso manualmente, pois algum código pode ser alcançável, mas simplesmente não testado.

E quanto ao código após retornos antecipados em blocos try-catch?

O código após um 'return' em um bloco 'try', mas antes do 'finally', é inalcançável. No entanto, blocos 'finally' sempre são executados, mesmo após 'returns'. Erro comum: colocar limpeza importante após um 'return' em um bloco 'try' em vez de no 'finally', onde realmente seria executada.

Código inalcançável pode causar erros de tempo de execução?

Não, porque nunca é executado. No entanto, ele pode referenciar variáveis indefinidas ou chamar funções inexistentes sem causar erros, o que o torna ainda mais insidioso. Este código quebrado passa em todos os testes porque nunca é executado, mas engana qualquer um que leia a base de código.

E quanto às feature flags e compilação condicional?

O código por trás de feature flags desabilitadas é alcançável em tempo de execução, mesmo que desabilitado no seu ambiente atual. Um código verdadeiramente inalcançável é estruturalmente impossível de ser executado devido ao fluxo de controle. O código com feature flags é condicionalmente alcançável e deve permanecer até que a funcionalidade seja totalmente removida.

Devo remover funções e imports não utilizados?

Sim, mas essa é uma categoria diferente de código morto. Código inalcançável é estruturalmente impossível de executar devido ao fluxo de controle. Funções não utilizadas são alcançáveis, mas nunca chamadas. Ambos devem ser removidos, mas exigem diferentes estratégias de detecção. A detecção de código não utilizado requer análise de programa completo, enquanto a detecção de código inalcançável funciona no nível da função.

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.