ti-enxame.com

Por que as exceções "sem cabeça" não devem ser detectadas, especialmente no código do servidor?

Estou confuso, porque em muitos lugares já li que as chamadas exceções "desatualizadas" (que resultam de bugs no código) não devem ser capturadas. Em vez disso, eles devem ter permissão para travar o aplicativo:

Pelo menos duas das três pessoas acima são autoridades estabelecidas.

Eu estou surpreso. Especialmente para alguns casos de uso (importantes!), Como código do lado do servidor, simplesmente não consigo entender por que a captura dessa exceção é subótima e por que o aplicativo deve travar.

Pelo que sei, a solução típica nesse caso é capturar a exceção, retornar HTTP 500 ao cliente, ter um sistema automático que envie um email de emergência para a equipe de desenvolvimento para que eles possam resolver o problema O mais rápido possível - mas não trava o aplicativo (uma solicitação deve falhar, não há nada que possamos fazer aqui, mas por que desativar todo o serviço e fazer com que todos os outros Não é possível usar nosso site? O tempo de inatividade é caro!). Estou incorreto?

Por que estou perguntando - estou constantemente tentando concluir um projeto de hobby, que é um jogo baseado em navegador no núcleo .net. Tanto quanto sei, em muitos casos, o framework faz para mim fora da caixa a coisa precisa que Eric Lippert e Stephen Cleary estão recomendando! - isto é, se o processamento de uma solicitação é lançada, a estrutura captura automaticamente a exceção e impede que o servidor trava. Em alguns lugares, no entanto, a estrutura não faz isso. Nesses locais, estou agrupando meu próprio código com try {...} catch {...} para capturar todas as possíveis exceções 'estúpidas'.

Um desses lugares, o AFAIK, são tarefas em segundo plano. Por exemplo, agora estou implementando um serviço de limpeza de proibição em segundo plano que deve limpar todas as proibições temporárias expiradas a cada poucos minutos. Aqui, eu estou usando algumas camadas de todos os blocos try:

try // prevent server from crashing if boneheaded exception occurs here
{
    var expiredBans = GetExpiredBans();
    foreach(var ban in expiredBans)
    {
        try // If removing one ban fails, eg because of a boneheaded problem, 
        {   // still try to remove other bans
            RemoveBan(ban);
        }
        catch
        {

        }
    }
}
catch
{

}

(Sim, meus blocos catch estão vazios no momento - estou ciente de que ignorar essas exceções é inaceitável, adicionar alguns registros está perpetuamente na minha lista de TODO)

Depois de ler os artigos aos quais vinculei acima, não posso mais continuar fazendo isso sem sérias dúvidas ... Não estou me dando um tiro no pé? Porque porque não?

Se e por que as exceções estúpidas nunca devem ser detectadas?

80
gaazkam

Você deve considerar o motivo/objetivo para lidar com uma exceção, como:

  • Executar algum tipo de ação corretiva ou de recuperação para que o aplicativo possa continuar significativamente; isso implica que a exceção e suas conseqüências sejam bem compreendidas
  • Para executar algum tipo de limpeza, para que o aplicativo seja restaurado para um estado consistente; novamente, as conseqüências da exceção devem ser totalmente compreendidas
  • Para capturar informações sobre a exceção para log e análise posterior
  • Falhar normalmente, como emitir algum tipo de mensagem amigável/significativa para o usuário em uma interface do usuário apropriada, em vez de qualquer mensagem ou código bruto reportado diretamente pela exceção; ao fazer isso, geralmente é aconselhável capturar os detalhes mais técnicos para análise pela equipe de desenvolvimento.

Se não houver um objetivo útil atendido pelo seu manipulador de exceções, um manipulador não deve estar lá e a exceção deve "borbulhar".

As exceções "Bonehead" implicam condições que não eram previstas quando o aplicativo foi inicialmente codificado. Exceções não antecipadas devem ter o máximo de detalhes capturados quanto possível, para que a causa possa ser determinada e medidas apropriadas sejam tomadas. Isso pode ser feito automaticamente pela estrutura de programação; Nesse caso, não convém manipulá-los explicitamente.

0
Zenilogix