J'ai une méthode où je traverse une liste et crée une liste. Ce faisant, j'appelle une méthode (createResult) afin que le résultat lève également une exception CustomException que je suis en train d'encapsuler en tant que ResultClassException. Mais je continue à recevoir une erreur en disant Exception non gérée.
Mon code:
private List<Result> getResultList(List<String> results) throws ResultClassException {
List<Result> resultList = new ArrayList<>();
results.forEach(
(resultName) -> {
if (!resultRepository.contains(resultName)) {
try {
final Result result = createResult(resultName);
resultList.add(result);
} catch (CustomException e) {
throw new ResultClassException("Error",e);
}
} else {
resultList.add(resultRepository.get(resultName));
log.info("Result {} already exists.", resultName);
}
}
);
return Collections.unmodifiableList(resultList);
}
Quelqu'un peut dire ce que je fais mal?
Vous avez probablement trop de responsabilités dans votre méthode. Vous devriez penser à le diviser en une méthode qui ne fait que des cartes et une autre qui les rassemble.
private List<Result> getResultList(List<String> names) throws ResultClassException {
try {
return names.stream()
.map(this::getOrCreateResult)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
} catch (RuntimeException e) {
if (e.getCause() instanceof CustomException) {
throw new ResultClassException("Error", e.getCause());
}
throw e;
// Or use Guava's propagate
}
}
private Result getOrCreateResult(String name) {
if (!resultRepository.contains(name)) {
try {
return createResult(name);
} catch (CustomException e) {
throw new RuntimeException(e);
}
} else {
log.info("Result {} already exists.", name);
return resultRepository.get(name);
}
}
Je ne suggérerais pas d'utiliser RuntimeException car cela vous mènerait à une mauvaise pratique de codage. Essayez de gérer ResultClassException dans la méthode d'appel de getResultList (...).
Vous ne pouvez pas gérer une exception vérifiée depuis l'intérieur de Streams
Une solution de contournement peut consister à lancer une RuntimeException
de createResult
ou à écrire une méthode pour encapsuler createResult
qui capturera et gérera l'exception vérifiée.
Avec les expressions lambda dans Java 8, vous représentez des classes internes. Ainsi, l’exception sera levée dans votre classe interne anonyme. Essayez d’ajouter que là où vous ajoutez votre , Lancez une nouvelle ResultClassException ("Erreur", e);
Thread.getAllStackTraces()
.keySet()
.stream()
.map(Thread::getStackTrace)
.map(Arrays::asList)
.forEach(list -> System.out.println(list.stream()
.map(i -> i.toString())
.collect(Collectors.joining("\n\t"))));
et voir le fil qui l'appelle. Vous verrez que votre exception est hors de la portée que vous attendiez avec les lambdas. Vous verrez que le flux crée de nombreux threads et que votre exception ne fait pas partie du thread que vous souhaitez. Vous pouvez envelopper votre méthode comme suit: Java 8 : Comment travailler avec des méthodes de lancement d'exception dans des flux?