The preferred pattern now is to use factory functions that can return either a fully-initialized object or an error.
Not every error is exceptional so not every error should use exceptions. This is especially important in lower level code where someone's exception is someone else's expected code path.