Я обычно буду использовать исключения в качестве крайней меры. Если это что-то, что должно никогда не произойти, и язык поддерживает его, я буду использовать какое-то утверждение (поскольку это, безусловно, ошибка какого-то рода).
Если этого можно избежать, я предпочту код ошибки.
Конечно, в некоторых языках есть несколько случаев, когда у вас мало выбора. Например, конструкторы c ++ не могут иметь возвращаемого значения, и, вероятно, плохо иметь частично сконструированный объект, поэтому иногда лучшим является выбрасывание исключения.
В общем, если вы можете проверить состояние ошибки и просто сообщить об ошибке вызывающей стороне без исключения, я бы предпочел это.