Bloco de try-catch fluente [fechado]
Tenho muito código desse tipo em meu aplicativo:
String authUserId = null;
try {
authUserId = webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
} catch (Exception e) {
// do nothing
}
Com cada fragmento, o objetivo é atribuir um valor se o método não lançar, nulo caso contrário. E embora o código acima funcione, certamente parece redundante e não simplificado.
Qual biblioteca Java pode tornar este código mais fluente? Como:
String authUserId = Try<String>.of(try -> {
return webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
});
ou algo mais simples.
ATUALIZAR:
Usando a biblioteca Vavr
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.3</version>
</dependency>
Resolvido isso com:
String authUserId = Try.of(() -> webTokenService.readUserIdFromToken(app.getMasterKey(), authToken)).get();
Respostas
Se você engolir a exceção completamente, esta não é realmente a melhor prática . Há um bom artigo sobre Exceção de Baeldung:
O acima é chamado engolir uma exceção. Na maioria das vezes, seria um pouco mesquinho para nós fazer isso porque não resolve o problema e impede que outro código seja capaz de resolver o problema também.
Encontrei uma biblioteca que implementa esse comportamento. No entanto, não é mantido há algum tempo. Por esse motivo, prefiro recomendar o Vavr . Ainda é necessário tratar a exceção. Um tutorial adicional também está disponível na Baeldung . Na documentação, há um pequeno exemplo de divisão de dois números:
int divide(int dividend, int divisor) {
return dividend / divisor;
}
Try<Integer> divide(Integer dividend, Integer divisor) {
return Try.of(() -> dividend / divisor);
}
Dado que engolir exceções silenciosamente é estúpido, nenhum.
É totalmente trivial escrever você mesmo:
class ShootMyselfInLegToolkit {
@FunctionalInterface
public interface PermissiveSupplier<T> {
T supply() throws Exception;
}
public <T> T ohMyLegs(PermissiveSupplier<T> supplier) {
try {
return supplier.supply();
} catch (Exception itHurts) {
return null; // dear lord.
}
}
}
Se você realmente quer enfiar isso em uma biblioteca, por favor.
As bibliotecas funcionais um pouco menos tolas funcionam assim: você fornece um fornecedor (permissivo - o jufSupplier do próprio java não pode fazer isso) e um manipulador de exceções, então fica assim:
Tool.tryGet(() -> Files.readAllLines(Paths.get("foo.txt")), ioex -> { code to handle the exception });
Você não pode simplesmente ir: Ei, sem colchetes, então eu nunca pressiono enter e, portanto, isso é 'menos linhas de código' e, portanto, 'mais simples', que ... bem, um modo muito estranho de pensar que você tem lá.
O que, em suas palavras, 'fluente' significa? Eu reconheço o termo aplicado a métodos setters, getters e builder e significa: "Sem prefixo get / set". Isso obviamente não se aplica aqui, então você claramente pensa que significa outra coisa. Não está nas especificações do idioma java, então talvez seja elaborado.
Não consigo ver como qualquer uma dessas coisas é mais simples de entender ou mais fácil de programar, além de lutas de estilo bobo. Eu acho que a maioria concordaria que a introdução de um monte de bibliotecas malucas SÓ porque você acha o estilo comumente usado na comunidade java repugnante - essa é uma saída ruim. Escrever código de maneira não idiomática é uma má ideia, independentemente do idioma e do quanto você odeia o estilo comum. Basta usar um idioma diferente ou ajustar suas preferências de estilo. Mais fácil falar do que fazer, talvez, mas mesmo assim - a melhor ideia, de longe.