In general, I use exceptions when the exception should cause a process to abort. When I'm going to do something about the problem and recover in some way, I try to prevent the exception from ever happening.
Like, if a parameter is passed in to a subroutine and I reasonably expect that it might be null, I'll check it for null. In real life, for example, a null String often is equivalent to a zero-length String, in which I'll just write < if (s==null) s=""; >.
But if a null String means that something has gone badly wrong and we should just quit the whole process and display a "Panic -- Abort -- World ending soon" type of message to the user, then an exception is very handy. You can throw the exception way down deep inside many layers of subroutines, and just catch it at the top, display the message, and you're done.
I often create my own exceptions for such conditions. Many of my programs are sprinkled with code like < throw new BadInputException("Customer number not found") > to just get me out, display a message, and quit. This really saves on deep nesting of IFs and constant checking of return values from subroutines.