2. Catch them lower down and regroup them to simplify them. (I have a networking package which throws a NetworkException on many exceptions -- in most cases if a network is down, it's down! This doesn't conflict with rule #1 since an exception is thrown.
3. Within a class its [sic] OK to have a private method return an error code. Reason, it means you don't have to go to the hassle of subclassing Exception again! (Its [sic] also confusing if you reuse a "private" exception in two classes since there may be little relation to what causes the exception.)
4. Between classes, methods should not return error codes but also throw exceptions -- Makes them easier to use elsewhere. Also, you don't have to make a comment about what a "-2" return code means.
5. Exception (pun intended!) to rule #4, it's OK to return a null as a condition. Basically, I'm so used to testing for nulls I would do it anyway.
6. At any level if you can add information to the message before throwing the exception, catch it and reissue it.