É uma boa prática capturar uma exceção verificada e lançar uma RuntimeException?

70

Li alguns códigos de um colega e descobri que ele muitas vezes captura várias exceções e sempre lança uma 'RuntimeException'. Eu sempre pensei que isso é uma prática muito ruim. Estou errado?

RoflcoptrException
fonte
17
"O preço das exceções verificadas é uma violação do Princípio Aberto / Fechado. Se você lançar uma exceção verificada de um método em seu código e a captura estiver três níveis acima, deverá declarar essa exceção na assinatura de cada método entre você e a captura Isso significa que uma alteração em um nível baixo do software pode forçar alterações de assinatura em muitos níveis mais altos ". —Robert C. Martin, «Código Limpo», página 107
Songo
6
É interessante notar que Jim Waldo reclama contra exceções não verificadas em "Java: The Good Parts" shop.oreilly.com/product/9780596803742.do dizendo que programadores adultos devem lançar apenas exceções verificadas. Nós o lemos em nosso JUG apenas 6 anos atrás, quando saiu e parecia um bom conselho! Agora, com programação funcional, as exceções verificadas são completamente difíceis de manejar. Idiomas como Scala e Kotlin nem sequer os têm. Também comecei a agrupar as exceções não verificadas.
GlenPeterson
@GlenPeterson, você também tem o conselho no FP para evitar execuções e usar tipos de soma
jk.
Há também o caso óbvio de interfaces funcionais: as interfaces funcionais embutidas (ou seja Function, Predicate, etc) não têm parametrizados joga cláusulas. Isso significa que você precisa capturar, agrupar e reproduzir novamente todas as exceções verificadas no loop interno de qualquer método stream (). Isso por si só sugere o equilíbrio para mim sobre se as exceções verificadas são uma má ideia.
Joel Cornett
Não há nada errado em criar subclasses personalizadas de RuntimeException para comunicar significado através da sua exceção.
Joel Cornett

Respostas:

55

Não conheço o contexto suficiente para saber se o seu colega está fazendo algo incorretamente ou não, então vou discutir sobre isso em um sentido geral.

Não acho que seja sempre uma prática incorreta transformar exceções verificadas em algum tipo de exceção de tempo de execução . As exceções verificadas geralmente são mal utilizadas e abusadas pelos desenvolvedores.

É muito fácil usar exceções verificadas quando elas não devem ser usadas (condições irrecuperáveis ​​ou mesmo controle de fluxo). Especialmente se uma exceção verificada for usada para condições das quais o chamador não pode se recuperar, acho que é justificado transformar essa exceção em uma exceção de tempo de execução com uma mensagem / estado útil. Infelizmente, em muitos casos, quando alguém se depara com uma condição irrecuperável, eles tendem a ter um bloco de captura vazio, que é uma das piores coisas que você pode fazer. Depurar esse problema é uma das maiores dificuldades que um desenvolvedor pode encontrar.

Portanto, se você acha que está lidando com uma condição recuperável, ela deve ser tratada adequadamente e a exceção não deve ser transformada em uma exceção de tempo de execução. Se uma exceção verificada for usada para condições irrecuperáveis, a transformação em uma exceção de tempo de execução será justificada .

c_maker
fonte
17
Na maioria das aplicações da vida real, existem muito poucas condições irrecuperáveis. Há quase um nível em que você pode e deve dizer "OK, esta ação falhou; portanto, mostramos / registramos uma boa mensagem de erro e continuamos com / aguardamos a próxima".
precisa
6
Isso é verdade, @ MichaelBorgwardt, mas o local para esse tipo de manipulação geralmente está no nível mais alto do aplicativo. Portanto, sempre que vejo desenvolvedores "manipulando" exceções em níveis mais baixos, geralmente é fácil remover a manipulação e apenas filtrar a exceção para cima. Por exemplo, uma estrutura da web como o JSF captura exceções no nível mais alto, imprime mensagens de log e continua processando outras solicitações (sem dizer que o tratamento padrão é adequado, apenas um exemplo).
Davids
40

Ele pode ser bom . Por favor leia:

http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html

Na maioria das vezes, o código do cliente não pode fazer nada sobre as SQLExceptions. Não hesite em convertê-los em exceções não verificadas. Considere o seguinte pedaço de código:

public void dataAccessCode(){
  try{
      ..some code that throws SQLException
  }catch(SQLException ex){
      ex.printStacktrace();
  }
} 

Esse bloco catch apenas suprime a exceção e não faz nada. A justificativa é que não há nada que meu cliente possa fazer sobre uma SQLException. Que tal lidar com isso da seguinte maneira?

public void dataAccessCode(){
   try{
       ..some code that throws SQLException
   }catch(SQLException ex){
       throw new RuntimeException(ex);
   }
} 

Isso converte SQLException em RuntimeException. Se ocorrer SQLException, a cláusula catch lança uma nova RuntimeException. O encadeamento de execução é suspenso e a exceção é relatada. No entanto, não estou corrompendo minha camada de objetos de negócios com manipulação desnecessária de exceções, especialmente porque ela não pode fazer nada sobre uma SQLException. Se minha captura precisar da causa da exceção raiz, posso usar o método getCause () disponível em todas as classes de exceção a partir do JDK1.4.

Lançar exceções verificadas e não conseguir se recuperar delas não ajuda.

Algumas pessoas até acham que as exceções verificadas não devem ser usadas. Consulte http://www.ibm.com/developerworks/java/library/j-jtp05254/index.html

Recentemente, vários especialistas conceituados, incluindo Bruce Eckel e Rod Johnson, declararam publicamente que, embora inicialmente concordassem completamente com a posição ortodoxa sobre exceções verificadas, eles concluíram que o uso exclusivo de exceções verificadas não é uma idéia tão boa quanto apareceu a princípio e que as exceções verificadas se tornaram uma fonte significativa de problemas para muitos projetos grandes. Eckel adota uma visão mais extrema, sugerindo que todas as exceções devem ser desmarcadas; A visão de Johnson é mais conservadora, mas ainda sugere que a preferência ortodoxa por exceções verificadas é excessiva. (Vale a pena notar que os arquitetos de C #, que quase certamente tinham muita experiência em usar a tecnologia Java, optaram por omitir exceções verificadas do design da linguagem, tornando todas as exceções desmarcadas.

Também a partir do mesmo link:

A decisão de usar exceções não verificadas é complicada e fica claro que não há resposta óbvia. O conselho da Sun é usá-los para nada, a abordagem C # (com a qual Eckel e outros concordam) é usá-los para tudo. Outros dizem: "existe um meio termo".

mrmuggles
fonte
13

Não, você não está errado. Sua prática é extremamente equivocada. Você deve lançar uma exceção que captura o problema que o causou. RunTimeException é amplo e abrangente. Deve ser um NullPointerException, ArgumentException etc. O que quer que descreva com precisão o que deu errado. Isso fornece a capacidade de diferenciar problemas com os quais você deve lidar e deixar o programa sobreviver versus erros que devem ser um cenário "Não passe". O que ele está fazendo é apenas um pouco melhor que "On Error Resume Next", a menos que haja algo faltando nas informações fornecidas na pergunta.

Equipamento
fonte
11
Obrigado pela dica. E se ele lançar uma exceção personalizada que ele implementou que herda diretamente de RuntimeException?
RoflcoptrException
27
@Gary Buyn: muitas pessoas pensam que exceção verificada é um experimento de projeto de linguagem falhou e eles são os únicos que devem ser usados com moderação, e não como uma questão de hábito.
precisa
7
@ Gary Buyn: Aqui está um artigo que descreve muito bem o debate: ibm.com/developerworks/java/library/j-jtp05254/index.html Observe também que, mais de 15 anos depois que o Java introduziu esse recurso, nenhum outro idioma o adotou, e o C ++ reprovou um recurso semelhante.
precisa
7
@c_maker: Na verdade, Bloch promove principalmente a visão ortodoxa, e seu comentário parece ser principalmente sobre o uso de mais exceções, ponto final. Na minha opinião, o único motivo válido para usar uma exceção verificada é uma condição que você espera que todos os chamadores tratem imediatamente.
precisa
14
O lançamento desnecessário de exceções verificadas viola o encapsulamento. O que você faz, se um método simples como 'getAccounts ()' lança uma 'SQLException', 'NullPointerException' ou 'FileNotFoundException'? Você pode lidar com isso? Você provavelmente apenas 'pegará (Exceção e) {}'. Além disso, essas exceções - sua implementação específica! Não deve fazer parte do contrato! Tudo que você precisa saber é que ocorreu um erro . E se a implementação mudar? De repente, tudo precisa mudar, porque o método não lança mais 'SQLException', mas uma 'ParseXMLException'!
KL
8

Depende.

Essa prática pode ser até sábia . Existem muitas situações (por exemplo, no desenvolvimento da Web), nas quais, se ocorrer alguma exceção, você não poderá fazer nada (porque não é possível, por exemplo, reparar o banco de dados inconsistente do seu código :-), somente o desenvolvedor pode fazê-lo). Nessas situações, é aconselhável agrupar a exceção lançada em uma exceção de tempo de execução e repeti-la novamente. Então você pode capturar todas essas exceções em alguma camada de manipulação de exceções, registrar o erro e exibir ao usuário um código de erro localizado + mensagem.

Por outro lado , se a exceção não for em tempo de execução (estiver marcada), o desenvolvedor da API indicará que essa exceção é solucionável e deve ser reparada. Se for possível, você definitivamente deve fazê-lo.

A outra solução pode ser a repetição da exceção verificada na camada de chamada, mas se você não conseguiu resolvê-la, onde ocorreu a exceção, provavelmente também não será possível resolvê-la aqui ...

malejpavouk
fonte
Você espera que o desenvolvedor da API saiba o que está fazendo e use bem as exceções verificadas. Comecei a ver APIs que favorecem o lançamento de exceções de tempo de execução e também a documenta para que o cliente tenha a opção de capturá-lo, se quiser.
c_maker
Um método que lança uma exceção geralmente não pode saber se um chamador pode se recuperar dele. Por outro lado, eu sugeriria que um método deveria deixar escapar apenas uma exceção verificada lançada por um método interno, se souber por que o método interno lançou a exceção e o motivo for consistente com a API do método externo. Se um método interno lança uma exceção verificada inesperadamente, deixá-lo borbulhar como uma exceção verificada pode deixar o chamador desinformado sobre o que aconteceu.
21814
2
Obrigado por mencionar o exception handling layer- por exemplo, em um aplicativo da web, um filtro.
Jake Toronto
5

Gostaria de receber comentários sobre isso, mas acho que há momentos em que isso não é necessariamente uma prática ruim. (Ou terrivelmente ruim). Mas talvez eu esteja errado.

Muitas vezes, uma API que você está usando lança uma exceção que você não pode imaginar sendo lançada na sua base de dados específica. Nesse caso, parece perfeitamente correto lançar uma RuntimeException com a exceção capturada como causa. Se essa exceção for lançada, provavelmente será a causa do erro de programação e não estará dentro dos limites da especificação correta.

Supondo que o RuntimeException não seja capturado e ignorado posteriormente, não é o caso de um OnErrorResumeNext.

O OnErrorResumeNext ocorre quando alguém pega uma exceção e simplesmente a ignora ou apenas a imprime. Essa é uma prática muito ruim em quase todos os casos.

user606723
fonte
Esse pode ser o caso próximo ao topo da árvore de chamadas, onde a única coisa que você pode fazer é tentar se recuperar normalmente e saber que o erro específico não ajudará. Nesse caso, pode ser necessário registrar o erro e seguir em frente (processar o próximo registro, informar ao usuário que ocorreu um erro, etc.). Caso contrário, não. Você sempre deve lidar com exceções o mais próximo possível do erro, e não envolvê-las como um elefante branco para o próximo manipulador.
Michael K
@MichaelK O problema é "o mais próximo possível do erro, na prática", na prática geralmente significa "através de várias camadas intermediárias que estão fora de seu controle direto". Por exemplo, se minha turma precisar implementar uma certa interface, minhas mãos estarão atadas. Isso pode acontecer arbitrariamente no fundo da árvore de chamadas. Mesmo quando as interfaces estão sob meu controle, adicionar declarações de arremessos pode fazer a abstração vazar se houver apenas um conjunto limitado de implementações concretas que possam ser projetadas. Fazer com que cada cliente pague o custo pelos detalhes de implementação de alguns não é uma grande troca de design da IMO.
Tim Seguine
4

TL; DR

Premissa

  • As exceções de tempo de execução devem ser lançadas quando o erro é irrecuperável: quando o erro está no código e não depende do estado externo (portanto, a recuperação estaria corrigindo o código).
  • As exceções marcadas devem ser lançadas quando o código estiver correto, mas o estado externo não for o esperado: nenhuma conectividade de rede, arquivo não encontrado ou corrompido etc.

Conclusão

Podemos repetir uma exceção verificada como uma exceção de tempo de execução se o código de propagação ou interface assumir que a implementação subjacente depende do estado externo, quando claramente não.


Esta seção discute o tópico de quando uma das exceções deve ser lançada. Você pode pular para a próxima barra horizontal se quiser ler uma explicação mais detalhada para a conclusão.

Quando é apropriado lançar uma exceção de tempo de execução? Você lança uma exceção de tempo de execução quando fica claro que o código está incorreto e que a recuperação é apropriada modificando o código.

Por exemplo, é apropriado lançar uma exceção de tempo de execução para o seguinte:

float nan = 1/0;

Isso gerará uma divisão por exceção de zero tempo de execução. Isso é apropriado porque o código está com defeito.

Ou, por exemplo, aqui está uma parte do HashMapconstrutor:

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                loadFactor);
    // more irrelevant code...
}

Para corrigir a capacidade inicial ou o fator de carga, é apropriado que você edite o código para garantir que os valores corretos sejam transmitidos. Não depende de algum servidor distante estar ativo, no estado atual do disco, um arquivo ou outro programa. O construtor que está sendo chamado com argumentos inválidos depende da correção do código de chamada, seja um cálculo incorreto que levou a parâmetros inválidos ou fluxo inadequado que perdeu um erro.

Quando é apropriado lançar uma exceção marcada? Você lança uma exceção verificada quando o problema é recuperável sem alterar o código. Ou, em termos diferentes, você lança uma exceção verificada quando o erro está relacionado ao estado enquanto o código está correto.

Agora, a palavra "recuperar" pode ser complicada aqui. Isso pode significar que você encontra outra maneira de atingir a meta: por exemplo, se o servidor não responder, tente o próximo servidor. Se esse tipo de recuperação é possível para o seu caso, isso é ótimo, mas essa não é a única coisa que significa recuperação - a recuperação pode estar simplesmente exibindo uma caixa de diálogo de erro para o usuário que explica o que aconteceu ou, se for um aplicativo de servidor, pode ser enviando um email para o administrador ou simplesmente registrando o erro de forma adequada e concisa.

Vamos pegar o exemplo mencionado na resposta dos mrmuggles:

public void dataAccessCode(){
   try{
       ..some code that throws SQLException
   }catch(SQLException ex){
       throw new RuntimeException(ex);
   }
}

Essa não é a maneira correta de lidar com a exceção verificada. A simples incapacidade de lidar com a exceção no escopo deste método não significa que o aplicativo deve ser travado. Em vez disso, é apropriado propagá-lo para um escopo mais alto como este:

public Data dataAccessCode() throws SQLException {
    // some code that communicates with the database
}

O que permite a possibilidade de recuperação pelo chamador:

public void loadDataAndShowUi() {
    try {
        Data data = dataAccessCode();
        showUiForData(data);
    } catch(SQLException e) {
        // Recover by showing an error alert dialog
        showCantLoadDataErrorDialog();
    }
}

As exceções verificadas são uma ferramenta de análise estática; elas deixam claro para um programador o que poderia dar errado em uma determinada chamada sem exigir que eles aprendam a implementação ou passem por um processo de tentativa e erro. Isso facilita garantir que nenhuma parte do fluxo de erros seja ignorada. A reconfiguração de uma exceção verificada como uma exceção de tempo de execução está funcionando contra esse recurso de análise estática que economiza trabalho.

Também vale a pena mencionar que a camada de chamada tem um contexto melhor do esquema maior de coisas, como foi demonstrado acima. Pode haver muitas causas para que dataAccessCodeisso seja chamado, o motivo específico da chamada é visível apenas para o chamador - portanto, ele pode tomar uma decisão melhor na recuperação correta em caso de falha.

Agora que esclarecemos essa distinção, podemos deduzir quando está correto repetir uma exceção verificada como uma exceção de tempo de execução.


Dado o exposto, quando é apropriado repetir novamente uma exceção verificada como uma RuntimeException? Quando o código que você está usando assume dependência do estado externo, mas você pode afirmar claramente que ele não depende do estado externo.

Considere o seguinte:

StringReader sr = new StringReader("{\"test\":\"test\"}");
try {
    doesSomethingWithReader(sr); // calls #read, so propagates IOException
} catch (IOException e) {
    throw new IllegalStateException(e);
}

Neste exemplo, o código está se propagando IOExceptionporque a API de Readerfoi projetada para acessar o estado externo; no entanto, sabemos que a StringReaderimplementação não acessa o estado externo. Nesse escopo, onde certamente podemos afirmar que as partes envolvidas na chamada não acessam o IO ou qualquer outro estado externo, podemos retroceder com segurança a exceção como uma exceção de tempo de execução, sem surpreender os colegas que desconhecem nossa implementação (e possivelmente assumindo que o código de acesso IO gerará um IOException).


O motivo para manter estritamente as exceções dependentes do estado externo verificadas é que elas não são determinísticas (diferentemente das exceções dependentes da lógica, que serão reproduzidas previsivelmente todas as vezes para uma versão do código). Por exemplo, se você tentar dividir por 0, sempre produzirá uma exceção. Se você não dividir por 0, nunca produzirá uma exceção e não precisará lidar com esse caso de exceção, porque isso nunca acontecerá. No entanto, no caso de acessar um arquivo, obter êxito uma vez não significa que você terá êxito na próxima vez - o usuário pode ter alterado as permissões, outro processo pode ter sido excluído ou modificado. Portanto, você sempre precisa lidar com esse caso excepcional ou provavelmente terá um bug.

Ben Barkay
fonte
2

Para aplicativos autônomos. Quando você sabe que seu aplicativo não pode lidar com a exceção, você poderia, em vez de lançar a RuntimeException verificada, lançar Error, deixar o aplicativo travar, esperar por relatórios de erros e corrigir seu aplicativo. (Veja a resposta de mrmuggles para uma discussão mais aprofundada dos prós e contras dos verificados versus não verificados.)

Kasper van den Berg
fonte
2

Essa é uma prática comum em muitas estruturas. Por exemplo, Hibernatefaz exatamente isso. A ideia é que as APIs não sejam invasivas para o cliente e Exceptionsejam invasivas, pois você deve escrever explicitamente o código para manipulá-las no local em que chama a API. Mas esse lugar pode não ser o lugar certo para lidar com a exceção em primeiro lugar.
Na verdade, para ser sincero, esse é um tópico "quente" e muitas disputas, por isso não tomarei partido, mas direi que o que seu amigo faz / propõe não é incomum ou incomum.

user10326
fonte
1

A coisa toda "exceção verificada" é uma má idéia.

A programação estruturada apenas permite que informações sejam passadas entre funções (ou, na linguagem Java, métodos) quando elas estão "próximas". Mais precisamente, as informações só podem se mover entre funções de duas maneiras:

  1. De um chamador a um chamado, via passagem de argumentos.

  2. De um chamado para o chamador, como valores de retorno.

Isso é fundamentalmente bom. É isso que permite que você raciocine sobre o seu código localmente: se você precisar entender ou modificar uma parte do seu programa, precisará apenas olhar para essa parte e outras partes "próximas".

No entanto, em algumas circunstâncias, é necessário enviar informações para uma função "distante", sem que ninguém no meio "saiba". É precisamente quando as exceções precisam ser usadas. Uma exceção é uma mensagem secreta enviada de um raiser (qualquer parte do seu código pode conter uma throwinstrução) para um manipulador (qualquer parte do seu código pode conter um catchbloco compatível com a exceção que foi thrown).

As exceções verificadas destroem o sigilo do mecanismo e, com ele, a própria razão de sua existência. Se uma função puder permitir que o chamador "conheça" uma informação, envie-a diretamente como parte do valor de retorno.

pyon
fonte
Pode ser bom mencionar que esse tipo de problema pode realmente causar estragos nos casos em que um método executa uma função que é fornecida pelo responsável pela chamada. O autor do método que recebe a função, em muitos casos, não tem motivos para saber nem se importar com o que o chamador espera que ele faça, nem com quais exceções o chamador pode estar esperando. Se o código que recebe o método não espera que ele lance uma exceção verificada, o método fornecido pode ter que quebrar todas as exceções verificadas que lançaria em exceções não verificadas que seu fornecedor poderia capturar.
Supercat
0

Isso pode depender caso a caso. Em certos cenários, é aconselhável fazer o que seu amigo está fazendo, por exemplo, quando você está expondo uma API para alguns clientes e deseja que o cliente tenha menos conhecimento dos detalhes da implementação, onde sabe que certas exceções de implementação podem ser específicas para detalhes de implementação e não podem ser expostos ao cliente.

Mantendo as exceções verificadas fora do caminho, você pode expor APIs que permitiriam ao cliente escrever código mais limpo, pois o próprio cliente pode estar pré-validando as condições excepcionais.

Por exemplo, Integer.parseInt (String) pega uma string e retorna o número inteiro equivalente a ela e lança NumberFormatException no caso de a string não ser numérica. Agora imagine que um envio de formulário com um campo ageseja convertido por esse método, mas o cliente já teria garantido a validação de sua parte; portanto, não faz sentido forçar a verificação da exceção.

user94369
fonte
0

Há realmente algumas perguntas aqui

  1. Você deve transformar exceções verificadas em não verificadas?

A regra geral é que as exceções que o chamador deve capturar e recuperar devem ser verificadas. Outras exceções (aquelas em que o único resultado razoável é abortar toda a operação ou quando você as considera improváveis ​​o suficiente para não se preocupar em se preocupar em lidar com elas especificamente) devem ser desmarcadas.

Às vezes, seu julgamento sobre se uma exceção merece captura e recuperação é diferente daquele da API com a qual você está trabalhando. Às vezes, o contexto é importante, uma exceção que vale a pena manipular em uma situação pode não valer a pena manipular em outra. Às vezes, sua mão é forçada pelas interfaces existentes. Portanto, sim, existem razões legítimas para transformar uma exceção verificada em uma exceção não verificada (ou em um tipo diferente de exceção verificada)

  1. Se você deseja transformar uma exceção não marcada em uma exceção marcada, como deve fazê-lo.

Primeiro e mais importante, certifique-se de usar o recurso de encadeamento de exceções. Dessa forma, as informações da exceção original não são perdidas e podem ser usadas para depuração.

Em segundo lugar, você precisa decidir que tipo de exceção usar. O uso de uma exceção simples de execução dificulta o chamador determinar o que deu errado, mas se o chamador está tentando determinar o que deu errado, isso pode ser uma indicação de que você não deveria ter alterado a exceção para torná-la desmarcada.

Peter Green
fonte
0

Em uma pergunta booleana, é difícil responder de maneira diferente após duas respostas controversas, mas eu gostaria de lhe dar uma perspectiva que, mesmo mencionada em poucos lugares, não foi enfatizada o suficiente pela importância que tem.

Com o passar dos anos, descobri que sempre alguém está confuso sobre um problema trivial, sem entender alguns dos fundamentos.

Camadas. Um aplicativo de software (pelo menos deveria ser) uma pilha de camadas, uma em cima da outra. Uma expectativa importante para boas camadas é que as camadas inferiores forneçam funcionalidade para componentes potencialmente múltiplos da camada superior.

Digamos que seu aplicativo tenha as seguintes camadas de baixo para cima NET, TCP, HTTP, REST, MODELO DE DADOS, NEGÓCIOS.

Se sua camada de negócios quiser executar uma chamada de descanso ... aguarde um segundo. Por que digo isso? Por que não disse solicitação HTTP ou transação TCP ou enviei pacotes de rede? Porque isso é irrelevante para a minha camada de negócios. Não vou lidar com eles, não vou olhar nos detalhes deles. Eu estou perfeitamente bem se eles estão profundos nas exceções que recebo como causa e não quero saber que elas existem.

Além disso, é ruim se eu souber detalhes, porque se amanhã eu quiser alterar os protocolos de transporte sublinhados que lidam com detalhes específicos do protocolo TCP, a minha abstração REST não fez um bom trabalho para se abstrair. a implementação específica.

Ao fazer a transição de uma exceção de camada para camada, é importante revisar todos os aspectos dela e que sentido isso fará para a abstração que a camada atual fornece. Pode ser substituir a exceção por outra, pode combinar várias exceções. Também pode fazer a transição deles de marcado para desmarcado ou vice-versa.

É claro que os lugares que você mencionou fazem sentido é uma história diferente, mas em geral - sim, pode ser uma boa coisa a se fazer.

gsf
fonte
-2

Na minha opinião,

No nível da estrutura, devemos ser exceções de tempo de execução de captura para reduzir mais blocos de tentativa de captura para o invocador no mesmo local.

No nível do aplicativo, raramente capturamos exceções de tempo de execução e acho que essa prática foi ruim.

Mark xie
fonte
11
E o que você fará com essas exceções no nível da estrutura?
Matthieu 13/12
Se houver uma camada de interface do usuário na estrutura que possa lidar com as exceções, a interface do usuário apresentará uma mensagem de erro de algum tipo indicando que algo deu errado. No caso de um aplicativo javascript de uma página, o aplicativo pode apresentar uma mensagem de erro. Concedido, a camada da interface do usuário deve lidar com o erro apenas se uma camada mais profunda realmente não puder se recuperar do erro.
Jake Toronto