Попробуйте ... поймать - для исключительных условий , то есть условий, которые не вызваны некорректным кодом, но могут просто изменить нормальный поток управления внешними непредсказуемыми событиями.
Утверждения для перехвата недействительного кода , то есть проверка, содержится ли в функции инвариант, проверка, вызывается ли внутренний метод с правильными аргументами (для публичного API вы все еще можете захотеть исключение для этого), и т.д.
Это мои основные рекомендации, но условные обозначения различаются в зависимости от ситуации и от языка к языку.
Когда вы сомневаетесь, вы можете спросить себя: должна ли эта специальная проверка безопасности присутствовать в коде выпуска после того, как мы протестируем и закончим все ? Если вы ответите «да, это все еще необходимо», вы, вероятно, захотите исключение. В противном случае вы, вероятно, захотите утверждение.