Use what fits for your situation, don't take the "when all I have's a hammer..." attitude to anything. Sometimes return codes make sense (eg in hot-loop code). Sometimes exceptions make sense (in constructors, for example. And no, two-step initialisation is not a good alternative.). Sometimes neither make sense and you actually should just terminate the whole program (out-of-memory). Sometimes contracts make more sense (precondition checks, validating function arguments).
Anyway, regardless of your strategy if you can provide some method of querying if a thing can succeed to your API, do so; it's always better to handle errors by just making sure you don't cause them!