Вместо того, чтобы помещать CustomException в RemoteException, вы можете изменить свой удаленный интерфейс следующим образом:
interface Foo extends Remote {
Object doSomething() throws CustomException, RemoteException;
}
Принцип здесь заключается в том, что только время выполнения RMI должно вызывать исключения RemoteException; они сигнализируют о некотором сбое в удаленном взаимодействии, а не в логике приложения. Фактически, конкретным реализациям даже не нужно объявлять RemoteException
.
Но это не относится к случаю, когда ваш сервис перехватывает исключение из какой-либо сторонней библиотеки, но не хочет раскрывать это в предложении throws.
public Object doSomething() throws CustomException {
try {
return theirSvc.getData();
} catch (ThirdPartyException ex) {
throw new CustomException("Failed to obtain requested data.");
// or: throw new CustomException("Failed to obtain requested data.", ex) ?
}
}
В этом случае я рекомендую вам не создавать «негерметичную абстракцию», когда в клиенте будет создана зависимость, которая иначе не должна была бы знать об этой сторонней библиотеке.
Обычно ведение журнала и является плохой практикой, поскольку одна и та же ошибка регистрируется повторно. Но в этом случае я думаю, что это оправдано, поскольку выброшенное исключение переносится на клиента; может быть полезно зарегистрировать его как на клиенте, так и на сервере. Таким образом, блок catch выглядит примерно так:
catch (ThirdPartyException ex) {
String message = "Failed to obtain requested data.";
log.error(message, ex);
throw new CustomException(message);
}
Таким образом, зависимость ThirdPartyException ограничивается сервером, журналы сервера содержат соответствующую информацию о реализации, а ошибка правильно передается клиенту.