That depends entirely on what's being done.
First, what is the actual behavior you want? If somebody is entering their own information, then a rejection and a dialog box saying, essentially, "You can't do that" is probably correct. If this is a data entry person, working from a pile of forms, a dialog box is probably also good, and the data entry person can put the invalid forms in a special pile. If you're doing batch processing, you don't want to bring things to a halt, but flag it and move to the next.
Once you have the behavior, you need to decide how you're going to implement it. Having a business rules checker that throws an exception is probably a good idea. Returning an return code and having it passed along is something else that can go wrong, and you certainly don't want the erroneous entries getting further.
Don't worry about performance expense. In the case of an individual entering data, it's trivial compared to the other times involved. Typically, the human will take the most time in that system. In the case of a batch job, if exceptions are a performance problem, you're entering far too many bad records, and in reality handling and re-entering all of those is going to be more of a problem than the exceptions.