Ao criar exceções, devo escrever mensagens que um usuário ou desenvolvedor deve entender? Quem realmente deve ser o leitor de mensagens de exceção?
Acho que as mensagens de exceção não são úteis e sempre tenho dificuldade em escrevê-las. Por convenção, o tipo de exceção já deve nos dizer por que algo não funcionou e as propriedades personalizadas podem adicionar ainda mais informações, como nomes de arquivos, índices, chaves etc. Então, por que repeti-lo na própria mensagem? Uma mensagem gerada automaticamente também pode fazer e tudo o que ela precisa conter é o nome da exceção com uma lista de propriedades adicionais. Isso seria exatamente tão útil quanto um texto manuscrito.
Não seria melhor não escrever mensagens, mas ter representantes de exceção especiais que cuidam da criação de mensagens significativas, talvez em idiomas diferentes, em vez de codificá-las no código?
Me perguntaram se uma dessas perguntas fornece uma resposta para minha pergunta:
- Como escrever uma boa mensagem de exceção
- Por que muitas mensagens de exceção não contêm detalhes úteis?
Eu li os dois e não fiquei feliz com as respostas deles. Eles falam sobre usuários em geral e se concentram no conteúdo da mensagem em si, e não no destinatário, e pode haver pelo menos dois deles: o usuário final e o desenvolvedor. Nunca sei com quem devo falar ao escrever mensagens de exceção.
Até acho que a famosa mensagem não tem nenhum valor real, pois apenas repete o nome do tipo de exceção em palavras diferentes. Por que se preocupar em escrevê-las? Eu posso gerá-los perfeitamente automaticamente.
Para mim, a mensagem de exceção carece de diferenciação de seus leitores. Uma exceção perfeita precisaria fornecer pelo menos duas versões da mensagem: uma para o usuário final e outra para o desenvolvedor. Chamar apenas uma mensagem é muito genérico. Uma mensagem do desenvolvedor deve ser escrita em inglês, mas a mensagem do usuário final pode precisar ser traduzida para outros idiomas. Não é possível conseguir tudo isso com apenas uma mensagem; portanto, uma exceção precisaria fornecer algum identificador à mensagem do usuário final que, como acabei de dizer, pode estar disponível em diferentes idiomas.
Quando leio todas as outras perguntas vinculadas, tenho a impressão de que uma mensagem de exceção realmente deve ser lida por um usuário final e não por um desenvolvedor ... uma única mensagem é como comer um bolo e também comê-lo.
fonte
Respostas:
Essas mensagens são para outros desenvolvedores
Espera- se que essas mensagens sejam lidas pelos desenvolvedores para ajudá-los a depurar o aplicativo. Isso pode assumir duas formas:
Depuração ativa. Na verdade, você está executando um depurador enquanto escreve o código e tenta descobrir o que acontece. Nesse contexto, uma exceção útil o guiará, facilitando a compreensão do que está acontecendo de errado ou, eventualmente, sugerindo uma solução alternativa (embora isso seja opcional).
Depuração passiva. O código é executado na produção e falha. A exceção é registrada, mas você recebe apenas a mensagem e o rastreamento de pilha. Nesse contexto, uma útil mensagem de exceção o ajudará a localizar rapidamente o bug.
Como essas mensagens geralmente são registradas, isso também significa que você não deve incluir informações confidenciais (como chaves privadas ou senhas, mesmo que possam ser úteis para depurar o aplicativo).
Por exemplo, o
IOSecurityException
tipo de exceção lançada ao gravar um arquivo não é muito explícito sobre o problema: é porque não temos permissões para acessar um arquivo? Ou talvez possamos ler, mas não escrever? Ou talvez o arquivo não exista e não tenhamos permissão para criar arquivos lá? Ou talvez esteja bloqueado (espero que o tipo de exceção seja diferente nesse caso, mas, na prática, os tipos às vezes podem ser enigmáticos). Ou talvez o Code Access Security nos impeça de realizar qualquer operação de E / S?Em vez de:
é muito mais explícito. Aqui, sabemos imediatamente que as permissões no diretório estão definidas corretamente (caso contrário, não poderemos saber que o arquivo existe), mas as permissões no nível do arquivo são problemáticas.
Isso também significa que, se você não puder fornecer nenhuma informação adicional que ainda não esteja no tipo da exceção, poderá manter a mensagem vazia.
DivisionByZeroException
é um bom exemplo em que a mensagem é redundante. Por outro lado, o fato de a maioria dos idiomas permitir que você lance uma exceção sem especificar sua mensagem é feito por um motivo diferente: porque a mensagem padrão já está disponível ou porque será gerada mais tarde, se necessário (e a geração dessa A mensagem está entre o tipo de exceção, que faz todo o sentido, "OOPly" falando).Observe que, por razões técnicas (geralmente de desempenho), algumas mensagens acabam sendo muito mais enigmáticas do que deveriam. .NET
NullReferenceException
:é um excelente exemplo de mensagem que não é útil. Uma mensagem útil seria:
Essas mensagens não são para usuários finais!
Os usuários finais não devem ver mensagens de exceção. Nunca. Embora alguns desenvolvedores acabem mostrando essas mensagens para os usuários, isso leva a uma má experiência e frustração do usuário. Mensagens como:
não significa absolutamente nada para o usuário final e deve ser evitado a todo custo.
O pior cenário é ter uma tentativa / captura global que lança a exceção para o usuário e sai do aplicativo. Um aplicativo que se preocupa com seus usuários:
Lida com exceções em primeiro lugar. A maioria deles pode ser manuseada sem incomodar o usuário. A rede está inoperante? Por que não esperar alguns segundos e tentar novamente?
Impede que um usuário leve o aplicativo a um caso excepcional. Se você pedir ao usuário para digitar dois números e dividir o primeiro pelo segundo, por que você deixaria o usuário digitar zero no segundo caso para culpá- lo alguns segundos depois? Que tal destacar a caixa de texto em vermelho (com uma dica útil de ferramenta informando que o número deve ser diferente de zero) e desativar o botão de validação até que o campo permaneça vermelho?
Convida um usuário a executar uma ação em um formulário que não seja um erro. Não há permissões suficientes para acessar um arquivo? Por que não pedir ao usuário para conceder permissões administrativas ou escolher um arquivo diferente?
Se nada mais funcionar, mostra um erro útil e amigável, escrito especificamente para reduzir a frustração do usuário, ajudar o usuário a entender o que deu errado e, eventualmente, resolver o problema, além de ajudá-lo a evitar o erro no futuro (quando aplicável).
Na sua pergunta, você sugeriu duas mensagens em uma exceção: uma técnica para desenvolvedores e outra para usuários finais. Embora essa seja uma sugestão válida em alguns casos menores, a maioria das exceções é produzida em um nível em que é impossível produzir uma mensagem significativa para os usuários. Pegue
DivisionByZeroException
e imagine que não poderíamos impedir a exceção de acontecer e não podemos lidar com isso sozinhos. Quando a divisão ocorre, a estrutura (já que é a estrutura, e não o código comercial, que gera a exceção) sabe qual será uma mensagem útil para um usuário? Absolutamente não:Em vez disso, pode-se deixar lançar a exceção e depois capturá-la em um nível superior, onde conhecíamos o contexto comercial e poderíamos agir de acordo para realmente ajudar o usuário final, mostrando assim algo como:
ou talvez:
Essas mensagens não são para análise
As mensagens de exceção também não devem ser analisadas ou usadas programaticamente. Se você acha que informações adicionais podem ser necessárias pelo responsável pela chamada, inclua-as na exceção lado a lado com a mensagem. Isso é importante, porque a mensagem está sujeita a alterações sem aviso prévio. O tipo faz parte da interface, mas a mensagem não é: nunca dependa dela para tratamento de exceções.
Imagine a mensagem de exceção:
Você deseja extrair os valores "500", "6", "4" e "377". Pense um pouco na abordagem que você usará para fazer a análise e só então continue lendo.
Você tem a ideia? Ótimo.
Agora, o desenvolvedor original descobriu um erro de digitação:
deveria estar:
Além disso, o desenvolvedor considera que o mês / semana / uma hora não são particularmente relevantes, portanto, ele também faz uma alteração adicional:
O que acontece com a sua análise?
Em vez de analisar, você pode usar propriedades de exceção (que podem conter o que se deseja, assim que os dados podem ser serializados):
Quão fácil é usar esses dados agora?
Às vezes (como no .NET), a mensagem pode até ser traduzida para o idioma do usuário (IMHO, a tradução dessas mensagens é absolutamente errada, pois é esperado que qualquer desenvolvedor possa ler em inglês). A análise dessas mensagens é quase impossível.
fonte
A resposta para isso depende inteiramente da exceção.
A pergunta mais importante a fazer é "quem pode resolver o problema?" Se a exceção for causada por um erro do sistema de arquivos enquanto você abre um arquivo, pode fazer sentido transmitir essa mensagem ao usuário final. A mensagem pode conter mais informações sobre como corrigir o erro. Eu posso pensar em um caso definitivo no meu trabalho em que eu tinha um sistema de plug-ins que carregava DLLs. Se um usuário digitou um erro de digitação na linha de comando para carregar o plug-in errado, a mensagem de erro subjacente do sistema realmente continha informações úteis para permitir a correção do problema.
Na maioria das vezes, no entanto, uma exceção não capturada não pode ser corrigida pelo usuário. A maioria deles envolve fazer alterações no código. Nesses casos, o consumidor da mensagem é claramente um desenvolvedor.
O caso de exceções detectadas é mais complicado porque você tem a oportunidade de processar adequadamente a exceção e lançar uma mais amigável. Uma linguagem de script que escrevi lançou exceções cuja mensagem era claramente destinada a um desenvolvedor. No entanto, como a pilha se desenrolou, adicionei traços de pilha legíveis pelo usuário de dentro da linguagem de script. Meus usuários raramente conseguiam entender a mensagem, mas podiam observar o rastreamento da pilha no script e descobrir o que acontecia 95% do tempo. Para os 5% restantes, quando eles me ligaram, tínhamos não apenas um rastreamento de pilha, mas uma mensagem pronta para desenvolvedor para me ajudar a descobrir o que estava errado.
No total, trato a mensagem de exceção como um conteúdo desconhecido. Alguém mais acima, que sabia mais sobre as implementações, deu ao meu software uma exceção. Às vezes, tenho um palpite de que conteúdo desconhecido será útil para um usuário final, às vezes não.
fonte