Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Внизу у нас (в рамках примера с cloud) код, который работает с этой cloud file system, и знать про HTTP ничего не должен.
Конечно же должен. Потому что клаудная "FS" — это некий Web API. Который, естественно, отвечает нам HTTP-шными кодами. Например — 403 с подробностями "token expired", которые совершенно непонятны среднему слою, зато понятны верхнему — который знает, что нужно токен обновить и попробовать снова.
PD>Безусловно не туда, потому что туда не получится. Туда — это в треш и угар, там бы его и должны были бы обработать и сделать HTTP иным способом, может быть.
Нет конечно. Там, в этом треше и угаре, просто нет и не может быть информации о том, что делать с HTTP исключениями. Эта информация есть только у того, кто вызывает треш и угар.
S>>Нет. Никто там от С++ не наследовался. И подозревать причины нет — все ходы записаны, включая ход мысли отцов-основателей.
PD>Допускаю. Равно как допускаю, что они неосознанно все же были под влиянием MSVC++. Не могли они его не знать.
Это очень странный ход рассуждений. Во-первых, с тем же успехом можно сказать, что они были под влиянием Pascal — ведь там тоже нет checked exceptions. То есть
наличие фичи откуда-то унаследовать можно; а вот унаследовать
отсутствие фичи....
Во-вторых, в С++ исключения всё же входят в сигнатуру, хоть и не проверяются. В дотнете — нет, не входят. То есть "наследование" какое-то очень однобокое.
PD>Тут будет, да. Но это особая ситуация. Произошло что-то непредвиденное.
Нет тут ничего особенного. Исключения и придуманы для "непредвиденных" ситуаций. Предвиденные неприятности принято обрабатывать явно.
PD>На все такие непредвиденные ситуации не напишешь throws. В конце концов NullPointerException может почти везде возникнуть
, не будешь же его писать в каждом методе.
Вовсе не везде. В целом, конечно же, крайне полезно знать, что в некоторых местах NullPointerException возникнуть не может.
PD>А вот "штатные" ошибки под контролем. Например, отсутствие файла, ошибка IO и все другие. Я не смогу написать код, который не учтет возможности их возникновения, мне просто не дадут это сделать. Мне придется решить, что я буду делать, если такая проблема возникнет. И это правильно. Если я пишу метод, читающий строки из файла, я должен написать код, который их читает и код, который что-то делает, если файла нет. Либо сам делает, либо декларирует — я не могу это обработать, оставляю обработку вызывающему коду. Четко и ясно. Входит в контракт метода.
Это всё работает только в плоских иерархиях вызовов. И совершенно никак не работает в коде на колбеках. Который, собственно, и является наиболее частоиспользуемым примером, когда мы контролируем "дно" и "крышу", а середину хотим куда-то делегировать.
PD>Кстати. Кроме твоих 4 вариантов, есть и 5-й. Выбросить-таки RuntimeException, но завернуть в него этот самый XyZException. На нижнем уровне его генерируют, на верхнем должны теперь понимать, коль скоро на верхнем мы его теперь хотим обрабатывать. А треш и угар все это пройдет как нож через масло.
Ну, я так и говорил, что способов три