Mam metodę ulepszającą budynek i chciałbym by wyglądała w następujący sposób -
public Either<? extends CityException, BuildingUpgradeRes> scheduleSawMillUpgrade(long cityId) {
return getCity(cityId)
.flatMap(pair -> {
City city = pair.getFirst();
CityEntity cityEntity = pair.getSecond();
return city
.upgradeResourceBuilding(city.getBuildings().getSawMill())
.map(result -> {
/** kod **/
return new BuildingUpgradeRes(result._1, executionTime.toLocalDateTime());
});
});
}
Założenie jest takie, że metoda jest używana z kontrolera i nie powinna być używana nigdzie indziej, odbiorca na froncie powinien zadecydować co zrobić z konkretnym typem błędu, a możliwe są dwa - CityNotFoundException lub NotEnoughResourcesException (wszystkie dziedziczą po CityException).
Metoda w serwisie budująca klasę domenową City ma sygnaturę
Either<CityNotFoundException, Pair<City, CityEntity>> getCity(long id) {}
A metoda w klasie domenowej ulepszająca budynek ma taką:
public <T extends CityInfrastructure<T> & ResourceInfrastructure> Either<NotEnoughResourcesException, Tuple2<ResourcesValue, T>> upgradeResourceBuilding(T building) {}
No i tak - to się nie kompiluje, rozumiem że to przez to jak działa .flatMap(). Mogę oczywiście pozmieniać by sygnatury zwracały CityException zamiast konkretnego wyjątku. Ale nie chcę tego robić z oczywistego względu - stracę istotną informację jaki konkretnie wyjątek zwraca dana metoda.
Mogę zrobić coś w stylu,
public Either<Either<CityNotFoundException, NotEnoughResourcesException>, BuildingUpgradeRes> scheduleSawMillUpgrade(long cityId) { }
ale to też mi się nie podoba. Wydaje mi się że Either jest źle używany no i co jeśli będzie jakiś trzeci możliwy wyjątek?
Więc pytanie - co robić w takiej sytuacji, jakie jest funkcyjne podejście do tego typu błędów?