Try-catch destina-se a ajudar no tratamento de exceções. Isso significa que, de alguma forma, isso ajudará nosso sistema a ser mais robusto: tente se recuperar de um evento inesperado.
Suspeitamos que algo possa acontecer durante a execução e a instrução (envio de uma mensagem), para que seja incluído na tentativa. Se algo quase inesperado acontecer, podemos fazer algo: escrevemos o problema. Acho que não ligamos para registrar a exceção. Eu acho que o bloco catch é para nos dar a oportunidade de se recuperar do erro.
Agora, digamos que nos recuperamos do erro, porque conseguimos consertar o que estava errado. Pode ser super legal fazer uma nova tentativa:
try{ some_instruction(); }
catch (NearlyUnexpectedException e){
fix_the_problem();
retry;
}
Isso cairia rapidamente no loop eterno, mas digamos que o fix_the_problem retorne true e tente novamente. Dado que não existe tal coisa em Java, como você resolveria esse problema? Qual seria o seu melhor código de design para resolver isso?
Isso é como uma pergunta filosófica, já que eu já sei o que estou pedindo não é diretamente suportado pelo Java.
fonte
remove()
partir de umjava.util.Queue
, que torce eInvalidElementException
quando a fila está vazia. Em vez de perguntar se está vazio, eu organizo as ações em um try-catch (que sob concorrência se torna obrigatório mesmo com o if anterior). Nesse caso, nocatch
bloco, eu pediria para encher a fila com mais elementos e, em seguida, tente novamente. Voila.Respostas:
Você precisa colocar seu
try-catch
interior em umwhile
loop como este: -Eu tomei
count
emaxTries
para evitar correr em um loop infinito, caso a exceção continue ocorrendo no seutry block
.fonte
maxTries
.infinite loop
Caso contrário, ele será executado se o usuário fornecer continuamente informações incorretas e, portanto, não sairá. De nada, porém. :)Solução obrigatória de "empresa":
E para ligar para:
fonte
Como sempre, o melhor design depende das circunstâncias particulares. Normalmente, porém, escrevo algo como:
fonte
continue
é necessário lá .. E você pode simplesmente inverter a condição if.Embora
try/catch
intowhile
seja uma estratégia bem conhecida e boa, quero sugerir uma ligação recursiva:fonte
limit
contaria o método que está sendo recorrente? Em oposição à versão loop, que vai jogar no nível 'original' ...void retry(int times) { (...) if (times==0) throw w; retry(times--);
Seu cenário exato tratado pelo Failsafe :
Bem simples.
fonte
Você pode usar anotações AOP e Java em jcabi-aspect (eu sou desenvolvedor):
Você também pode usar
@Loggable
e@LogException
anotações.fonte
fix_the_problem();
no bloco catchA maioria dessas respostas é essencialmente a mesma. A minha também é, mas essa é a forma que eu gosto
fonte
fix_the_problem
após a última tentativa. Isso pode ser uma operação cara e pode levar algum tempo.if (tryCount < max) fix()
- mas esse é o formato de uma abordagem geral; os detalhes dependeriam de um caso específico. Há também um secador de goiaba que eu estou olhando.Spring AOP e solução baseada em anotação:
Uso (
@RetryOperation
é nossa anotação personalizada para o trabalho):Para isso, precisaremos de duas coisas: 1. uma interface de anotação e 2. um aspecto de primavera. Aqui está uma maneira de implementar estes:
A interface de anotação:
O aspecto da primavera:
fonte
Use um
while
loop comstatus
sinalizador local . Inicialize o sinalizador comofalse
e defina-otrue
quando a operação for bem-sucedida, por exemplo, abaixo:Isso continuará tentando novamente até que seja bem-sucedido.
Se você deseja tentar novamente apenas um certo número de vezes, use também um contador:
Isso tentará no máximo 10 vezes, se não for bem-sucedido até então, um sairá se for bem-sucedido antes da mão.
fonte
!success
no seu tempo, você pode simplesmente sair do tempo em que o sucesso é verdadeiro.success
lugar em seucatch
. Portanto, parece redundante verificar isso a cada execuçãocatch
.success
. Experimente.Esta é uma pergunta antiga, mas uma solução ainda é relevante. Aqui está minha solução genérica no Java 8 sem usar nenhuma biblioteca de terceiros:
Vamos ter um caso de teste como:
fonte
Uma maneira simples de resolver o problema seria agrupar a tentativa / captura em um loop while e manter uma contagem. Dessa forma, você pode impedir um loop infinito verificando uma contagem em relação a outra variável enquanto mantém um log de suas falhas. Não é a solução mais requintada, mas funcionaria.
fonte
Use um tempo para projetar o bloco de repetição.
fonte
Caso seja útil, mais algumas opções a considerar, todas reunidas (arquivo de parada em vez de novas tentativas, suspensão, continuar um loop maior), tudo isso possivelmente útil.
fonte
Você pode usar https://github.com/bnsd55/RetryCatch
Exemplo:
Em vez de
new ExampleRunnable()
você pode passar sua própria função anônima.fonte
Se nem todas as exceções justificarem uma nova tentativa, apenas algumas. E se pelo menos uma tentativa tiver que ser feita, aqui está um método utilitário alternativo:
Uso:
fonte
Tudo o que um Try-Catch faz é permitir que seu programa falhe normalmente. Em uma instrução catch, você geralmente tenta registrar o erro e, se necessário, reverter as alterações.
fonte
(!finished)
?while(finished)
. Eu prefiro usar a versão mais detalhada.while(!finished)
parecewhile (finished)
??IsPopulated()
que apenas retorna!IsNullOrEmpty()
para garantir que minha intenção seja compreendida por todos os desenvolvedores.Eu sei que já existem muitas respostas semelhantes aqui, e as minhas não são muito diferentes, mas eu as publicarei de qualquer maneira, porque lida com um caso / problema específico.
Às vezes, ao lidar com o
facebook Graph API
in,PHP
você recebe um erro, mas tentar novamente a mesma coisa imediatamente dará um resultado positivo (por várias razões mágicas da Internet que estão além do escopo desta pergunta). Nesse caso, não há necessidade de corrigir nenhum erro, mas simplesmente tente novamente porque houve algum tipo de "erro no facebook".Este código é usado imediatamente após a criação de uma sessão no facebook:
Além disso, ao contar o
for
loop até zero ($attempt--
), é muito fácil alterar o número de tentativas no futuro.fonte
A seguir, é minha solução com uma abordagem muito simples!
fonte
Não tenho certeza se essa é a maneira "profissional" de fazer isso e não tenho certeza se ela funciona para tudo.
fonte
https://github.com/tusharmndr/retry-function-wrapper/tree/master/src/main/java/io
fonte
Aqui, uma abordagem reutilizável e mais genérica para Java 8+ que não requer bibliotecas externas:
Uso:
fonte
O problema com as soluções restantes é que, a função correspondente tenta continuamente sem um intervalo de tempo intermediário, sobrecarregando a pilha.
Por que não apenas
try
cada segundo e ad eternum ?Aqui, uma solução usando
setTimeout
e uma função recursiva:Substitua a função
Run()
pela função ou código que você deseja substituir atry
cada segundo.fonte
Experimente usar a anotação springs @Retryable, o método abaixo tentará novamente por 3 tentativas quando ocorrer RuntimeException
fonte
Abaixo do snippet, execute algum snippet de código. Se houver algum erro ao executar o trecho de código, durma por milissegundos e tente novamente. Link de referência .
fonte
Aqui está minha solução semelhante a algumas outras que podem envolver uma função, mas permite que você obtenha o valor de retorno das funções, se tiver êxito.
fonte