---
title: "Ocultação de erros"
type: "antipattern"
slug: "error-hiding"
url: "http://localhost:3000/pt-br/antipatterns/error-hiding.md"
description: "Deixar de relatar os detalhes de um erro"
---
# Ocultação de erros

> Deixar de relatar os detalhes de um erro

Na [programação de computadores](https://en.wikipedia.org/wiki/Computer%5Fprogramming "Computer programming"), a **ocultação de erros** (ou **engolir erros**) é a prática de capturar um erro ou [exceção](https://en.wikipedia.org/wiki/Exception%5F%28computing%29 "Exception (computing)") e então continuar sem registrar, processar ou relatar o erro às outras partes do software. Tratar erros dessa maneira é considerado uma má prática e um [antipadrão](https://en.wikipedia.org/wiki/Anti-pattern "Anti-pattern") na [programação de computadores](https://en.wikipedia.org/wiki/Computer%5Fprogramming "Computer programming"). Em linguagens com [suporte a tratamento de exceções](https://en.wikipedia.org/wiki/Exception%5Fhandling#Exception%5Fsupport%5Fin%5Fprogramming%5Flanguages "Exception handling"), essa prática é chamada de **engolir exceções**.

Erros e exceções têm várias finalidades:

* Ajudar os mantenedores do software a localizar e entender problemas que ocorrem quando um usuário está executando o software, quando combinados com um sistema de registro (logging)
* Fornecer informações úteis ao usuário do software, quando combinados com mensagens de erro significativas, códigos de erro ou tipos de erro exibidos em uma interface, como mensagens de console ou como dados retornados por uma [API](https://en.wikipedia.org/wiki/API "API") (dependendo do tipo de software e do tipo de usuário)
* Indicar que a operação normal não pode continuar, de modo que o software possa recorrer a formas alternativas de executar a tarefa exigida ou abortar a operação.

Quando os erros são engolidos, essas finalidades não podem ser cumpridas. As informações sobre o erro são perdidas, o que torna muito difícil localizar problemas. Dependendo de como o software é implementado, isso pode causar efeitos colaterais não intencionais que se propagam em cascata para outros erros, desestabilizando o sistema. Sem informações sobre a causa raiz do problema, é muito difícil descobrir o que está dando errado ou como corrigi-lo.

## Exemplos

### Linguagens com tratamento de exceções

Neste exemplo em [C#](https://en.wikipedia.org/wiki/C%5FSharp%5F%28programming%5Flanguage%29 "C Sharp (programming language)"), mesmo que o código dentro do bloco _try_ lance uma exceção, ela é capturada pela cláusula _catch_ genérica. A exceção foi engolida e é considerada tratada, e o programa continua.

try {
  throw new Exception();
} catch {
  // não faz nada
}

Neste exemplo em [PowerShell](https://en.wikipedia.org/wiki/PowerShell "PowerShell"), a cláusula _trap_ captura a exceção que está sendo lançada e a engole ao continuar a execução. A mensagem _"I should not be here"_ é exibida como se nenhuma exceção tivesse ocorrido.

&{
  trap { continue }
  throw
  write-output "I should not be here"
}

Engolir exceções também pode acontecer se a exceção for tratada e relançada como uma exceção diferente, descartando a exceção original e todo o seu contexto.

Neste exemplo em C#, todas as exceções são capturadas independentemente do tipo, e uma nova exceção genérica é lançada, mantendo apenas a mensagem da exceção original. O stacktrace original é perdido, junto com o tipo da exceção original, qualquer exceção da qual a original fosse um invólucro e qualquer outra informação capturada no objeto da exceção.

try {
    // faz algo
} catch (Exception ex) {
    // talvez faça algum tratamento local da exceção
    throw new Exception(ex.Message);
}

Uma forma melhor de relançar exceções sem perder informações é lançar a exceção original a partir da cláusula _catch_:

try {
    // faz algo
} catch (Exception ex) {
    // faz algum tratamento local da exceção
    throw;
}

Como alternativa, é possível criar uma nova exceção que envolve a exceção original, de modo que quaisquer outros tratadores tenham acesso a ambas:

try {
    // faz algo
} catch(Exception ex) {
    // talvez faça algum tratamento local da exceção
    throw new CustomException(ex);
}

### Outras linguagens

Em [Go](https://en.wikipedia.org/wiki/Go%5F%28programming%5Flanguage%29 "Go (programming language)"), os erros são propagados retornando um objeto _Error_ junto com o valor de retorno normal da função. Ele pode ser ignorado, como neste exemplo.

f, _ := "I should not be here", errors.New("")
fmt.Print(f)

No caso das chamadas de sistema em [C](https://en.wikipedia.org/wiki/C%5F%28programming%5Flanguage%29 "C (programming language)"), os erros são indicados pelo valor de retorno da chamada ser _NULL_, e as informações de erro são armazenadas em uma variável global _errno_. Este código garante que o _file_ seja válido antes de acessá-lo, mas, se _fopen_ falhou, o erro é engolido.

FILE *file = fopen("", "r");
if (file) {
  // faz algo com o arquivo
}

## Causas

A causa subjacente mais comum de engolir erros é a falta de boas ferramentas e processos de registro (logging) enquanto o desenvolvedor está construindo o software. Diante de um erro que não pode ser facilmente tratado, se o desenvolvedor tiver boas ferramentas de registro, registrar um erro inesperado não custa ao desenvolvedor tempo nem esforço algum. Registrar o erro deve ser simples (uma chamada de método), rápido (sem impacto no desempenho da aplicação), seguro (não levanta nenhum erro ou exceção) e garantir que todas as informações sejam salvas, registrando o tipo de erro e quaisquer dados relevantes associados a ele, o [stacktrace](https://en.wikipedia.org/wiki/Stack%5Ftrace "Stack trace") do erro (para que o desenvolvedor possa identificar exatamente onde o erro ocorreu e quais instruções o antecederam) e o instante (timestamp) do erro.

### Tratadores de exceção temporários

Em linguagens com [exceções verificadas](https://en.wikipedia.org/wiki/Checked%5Fexceptions "Checked exceptions"), todas as exceções levantadas em um método devem ser listadas na assinatura desse método. Ao prototipar e implementar software, o código muda com frequência, o que significa que o tipo de exceções que podem ser levantadas em um método também muda com frequência. Ter de ajustar a assinatura do método toda vez que algo muda torna o desenvolvimento mais lento e pode ser frustrante, de modo que engolir exceções como medida temporária ao fazer grandes alterações no código é tentador. Esse código temporário de tratamento de exceções pode acabar indo parar na [base de código](https://en.wikipedia.org/wiki/Codebase "Codebase") lançada.

Mesmo em linguagens sem exceções verificadas, pode acontecer de se adicionarem tratadores de exceção temporários durante grandes alterações no código para acelerar a prototipagem, o que pode levar a engolir erros.

### Evitar travamentos

Em situações em que o software não pode travar por nenhum motivo, engolir erros é uma prática na qual um programador pode facilmente cair. Por exemplo, espera-se que um [plugin](https://en.wikipedia.org/wiki/Plug-in%5F%28computing%29 "Plug-in (computing)") em execução dentro de outra aplicação trate todos os erros e exceções de forma a não travar a aplicação na qual está incorporado. A captura indiscriminada de erros e exceções é um padrão no qual é fácil cair ao tentar evitar travamentos a todo custo e, quando se combina isso com ferramentas de registro ruins, engolir erros pode acontecer.

### Ocultar a complexidade dos usuários

Ao mostrar erros aos usuários, é importante transformar erros técnicos crípticos em mensagens que expliquem o que aconteceu e quais ações o usuário pode tomar, se houver, para corrigir o problema. Ao realizar essa tradução de erros técnicos em mensagens significativas para o usuário, erros específicos são frequentemente agrupados em erros mais genéricos, e esse processo pode levar a mensagens de usuário tão inúteis que o usuário não sabe o que deu errado ou como corrigir. No que diz respeito ao usuário, o erro foi engolido.
