Aqui está um cenário padrão:
if(string.IsNullOrEmpty(Configuration.AppSettings["foobar"]))
throw new SomeStandardException("Application not configured correctly, bozo.");
O problema é que não tenho muita certeza de qual exceção SomeStandardException
deve ser.
Examinei o Framework 3.5 e encontrei dois prováveis candidatos: ConfigurationException
e ConfigurationErrorsException
.
System.Configuration.ConfigurationException
A exceção que é lançada quando ocorre um erro no sistema de configuração.
Observações
AConfigurationException
exceção será lançada se o aplicativo tentar ler ou gravar dados no arquivo de configuração, mas não tiver êxito. Alguns motivos possíveis para isso podem incluir XML malformado no arquivo de configuração, problemas de permissão de arquivo e propriedades de configuração com valores inválidos.Nota:
O
ConfigurationException
objeto é mantido para compatibilidade com versões anteriores. OConfigurationErrorsException
objeto o substitui pelo sistema de configuração.
Essa exceção realmente parece perfeita para o que eu preciso, mas foi marcada como obsoleta.
Isso nos leva ao intrigante ConfigurationErrorsException
:
System.Configuration.ConfigurationErrorsException
O valor atual não é um dos valores EnableSessionState.
Como você pode ver, sua documentação é completamente inútil. (É assim na ajuda local e on-line.) Um exame da turma mostra que é um exagero drástico para o que eu quero.
Em poucas palavras, preciso de uma exceção padrão que deve ser lançada quando uma configuração do aplicativo estiver ausente ou contiver um valor inválido. Você pensaria que o Framework tivesse uma exceção para os aplicativos. (Aparentemente, mas foi marcado como obsoleto e foi substituído por algo muito maior em escopo.)
Quais soluções, se houver, vocês estão usando para isso, e eu vou ter que aceitar e lançar minha própria exceção?
Editar Adendos
Alguns perguntaram se eu poderia ou não fornecer um valor padrão e continuar. Em certos casos, sim, e nesses casos, a exceção não seria lançada. No entanto, para determinadas configurações, isso não se aplica. Por exemplo: nomes e credenciais do servidor de banco de dados, servidores de autenticação e caminhos para aplicativos de terceiros instalados.
Também vale a pena notar que o aplicativo no qual estou trabalhando principalmente é um aplicativo de console em execução no modo em lote e quero que ele lance uma exceção capturada pelo método principal e registrada adequadamente se a coisa não estiver configurada adequadamente. (É o código legado que eu herdei e atualmente apenas assume que tudo é pêssego.)
fonte
System.Configuration.ConfigurationErrorsException
foi atualizada.Respostas:
Você não está limitado ao lançar exceções às exceções existentes no Framework. Se você decidir usar exceções existentes, não precisará seguir absolutamente a documentação à risca. A documentação descreverá como a estrutura usa uma determinada exceção, mas não implica nenhuma limitação em como você escolhe usar / reutilizar uma exceção existente.
É seu aplicativo - desde que você o documente e indique claramente a exceção que será lançada no caso específico de um valor de configuração ausente, você poderá usar qualquer exceção que desejar. Se você deseja uma indicação muito específica de um valor ausente , considere gravar sua própria exceção ConfigurationSettingMissing:
EDIT: Escrever sua própria exceção neste caso traz o benefício adicional de garantir que nunca haverá qualquer confusão sobre de onde a exceção vem - a estrutura ou seu aplicativo. A estrutura nunca lançará suas exceções personalizadas.
UPDATE: Concordo com os comentários, por isso alterei a subclasse para ConfigurationErrorsException from Exception. Eu acho que geralmente é uma boa ideia subclassar exceções personalizadas das exceções existentes do Framework sempre que possível, evitando a classe Exception, a menos que você precise de uma exceção específica do aplicativo.
fonte
Pessoalmente, eu usaria InvalidOperationException , pois é um problema com o estado do objeto - não com o sistema de configuração. Afinal, você não deve permitir que essas configurações sejam definidas por código e também não? A parte importante aqui não é que não havia linha no app.config, mas que uma informação necessária não estava presente.
Para mim, o ConfigurationException (e seu substituto, o ConfigurationErrorsException - apesar dos documentos enganosos do MSDN) são por causa de erros ao salvar, ler etc. da Configuração.
fonte
Como Daniel Richardson disse, o ConfigurationErrorsException é o único a ser usado. Em geral, é recomendável criar seus próprios tipos de exceção personalizados se você tiver um cenário para lidar com eles. No caso de erros de configuração, que geralmente são fatais, esse raramente é o caso; portanto, geralmente é mais apropriado reutilizar o tipo ConfigurationErrorsException existente.
Antes do .NET 2.0, a recomendação era usar System.Configuration.ConfigurationException . O ConfigurationException ficou obsoleto no .NET 2.0, por motivos que nunca foram claros para mim, e a recomendação foi alterada para usar o ConfigurationErrorsException.
Eu uso um método auxiliar para lançar a exceção, para que seja fácil alterar a exceção que está sendo lançada em um local ao migrar do .NET 1.x para 2.0, ou se a Microsoft decidir alterar a recomendação novamente:
fonte
Que tal
System.Configuration.SettingsPropertyNotFoundException
?fonte
ConfigurationErrorsException
é a exceção correta a ser lançada na situação que você descreve. Uma versão anterior da documentação do MSDN paraConfigurationErrorsException
faz mais sentido.http://msdn.microsoft.com/en-us/library/system.configuration.configurationerrorsexception(VS.80).aspx
O resumo e as observações anteriores do MSDN são:
ConfigurationErrorsException
exceção é lançada quando ocorre algum erro enquanto as informações de configuração estão sendo lidas ou gravadas.fonte
A classe ConfigurationElement (que é a classe base de muitas classes relacionadas à configuração, como ConfigurationSection) possui um método chamado OnRequiredPropertyNotFound (também existem outros métodos auxiliares). Talvez você possa ligar para eles.
O OnRequiredPropertyNotFound é implementado assim:
fonte
Eu sugaria e rolaria por conta própria ... mas antes de fazer isso, é possível que o sistema assuma um valor padrão para esta configuração? Geralmente, eu tento fazer isso para todas as configurações que podem ser perdidas pelo pessoal da Ops Management ... (ou talvez eu deva dizer, para o maior número possível de configurações - para algumas, claramente não é apropriado que o sistema tome uma decisão padrão. ..)
em geral, uma exceção personalizada não exige muito esforço ... aqui está um exemplo ...
fonte
Um método alternativo que você poderia usar para seus arquivos de configuração seria usar seções de configuração personalizadas em vez de
AppSettings
. Dessa forma, você pode especificar que uma propriedadeIsRequired
e o sistema de configuração cuidem dessa verificação para você. Se a propriedade estiver ausente, ela será lançada,ConfigurationErrorsException
então suponho que seja compatível com a resposta de que você deve usar essa exceção no seu caso.fonte
Minha regra geral seria:
Se o caso da configuração ausente não for muito comum e eu acredito que nunca desejaria lidar com esse caso de maneira diferente de outras exceções, apenas uso a classe "Exception" básica com uma mensagem apropriada:
lançar nova exceção ("minha mensagem aqui")
Se eu quiser, ou achar que há uma alta probabilidade de que eu queira lidar com esse caso de uma maneira diferente da maioria das outras exceções, eu lançaria meu próprio tipo, como as pessoas já sugeriram aqui.
fonte
Costumo discordar da premissa de sua pergunta:
De acordo com a documentação do MSDN em System.Exception ( Exception Class , você realmente não deve lançar exceções para erros de entrada do usuário, por motivos de desempenho (o que foi apontado por outros usuários no Stack Overflow e em outros lugares). bem - por que sua função não pode retornar false se a entrada do usuário é inserida incorretamente e depois o aplicativo é encerrado normalmente? Isso parece ser mais um problema de design do que um problema com o qual a exceção deve ser lançada.
Como outros já apontaram, se você realmente tiver que lançar uma exceção - por qualquer motivo - não há motivo para não definir seu tipo de exceção herdando System.Exception.
fonte
Você pode tentar herdar a exceção XML ou apenas usá-la.
fonte