Хотя я в принципе согласен, что
Всегда имеет смысл использовать throw самое конкретное исключение
это может или не может быть необходимо.
Я написал фреймворк для огромного проекта, и вначале я был очень увлечен проектированием матери всех систем сообщений об ошибках - это было бы прекрасно. Частью проекта была иерархия классов исключений.
И я все это выбросил. Не потому что это было плохо, я бросил это, потому что это было совершенно ненужно.
Конечно, мы обрабатывали существующие исключения, но не было необходимости в более чем одном настраиваемом исключении, потому что, как оказалось, каждое из наших "исключительных условий" было тем, что я называю ошибкой "программиста", по сути, неудачей утверждение.
Лучшим решением в нашем случае была система, которая записывала различительный след хлебных крошек в файл и затем отображала эквивалент «ой, извините!» в следующем соответствующем состоянии ожидания вместе со ссылкой на техподдержку.
Это было наше приложение. Возможно, вы пишете библиотеку, и в этом случае игнорируйте все, что я только что сказал.
Итак, извините, это звучит как полицейский, но ответ на ваш вопрос:
Это зависит.