Исключения следует использовать для исключительных условий. Я бы сказал, что неудачная сборка не является исключительной , поэтому вам следует, чтобы интерфейс вашего компилятора возвращал значение, указывающее на успех или неудачу (например, bool или enum), и предоставлял интерфейс для возврата списка ошибки. Это может быть так же просто, как возвращение строки всех ошибок, объединенных вместе, или это может быть что-то вроде того, как вы передаете ему выходной поток заранее, и он регистрирует каждую ошибку в этом потоке, когда сталкивается с ними.