You are right that #2 is well served by exceptions when done right. It's also well served by checking locally and returning your own error status. Both ways can be done well. IME exceptions tend to pass the buck to the caller when they shouldn't, in the hands of mediocre programmers.