I would never mix the two models.. it's too hard to convert from one to the other as you move from one part of the stack which is using error codes, to a higher piece that is using exceptions.
Exceptions are for "anything that stops or inhibits the method or subroutine from doing what you asked it to do" ... NOT to pass messages back abot irregularities or unusual circumstances, or the state of the system.. etc. Use return values or by reference (or out) parameters for that.
Exceptions allow methods to be written (and utilized) with semantics that are dependant on the method's function, i.e. a method that returns an Employeee object or List of Employees can be typed to do just that, and you can utilize it by calling.
Employee EmpOfMonth = GetEmployeeOfTheMonth();
With error codes, all methods return an error code, so, for those that need to return something else to be used by the calling code, you have to pass a reference variable to be populated with that data, and test the return value for the error code, and handle it, on every function or method call.
Employee EmpOfMonth;
if (getEmployeeOfTheMonth(ref EmpOfMonth) == ERROR)
// code to Handle the error here
If you code so that each method does one and only one simple thing, then you should throw an exception whenever the method cannot accomplish the method's desired objective. Exceptions are much richer and easier to use in this way than error codes. Your code is much cleaner - The standard flow of the "normal" code path can be devoted strictly to the case where the method IS able to accomplish what you wanted it to do... And then the code to clean up, or handle the "exceptional" circumstances when something bad happens thar prevents the method from completing successfully can be siloed away from the normal code. Additionally, if you can't handle the exception where it occurred, and must pass it up the stack to a UI, (or worse, across the wire from a mid-tier component to a UI), then with exception model, you don;t need to code every intervening method in your stack to recognize and pass the exception up the stack... The exception model does this for you automagically.... With error codes, this piece of the puzzle can get onerous very rapidly.