The nice thing about NaN is that you can just do a calculation as normal, and check for NaN at the very end. This means you don't have to do an expensive test/branch after every arithmetic or other numeric operation. The hardware is much, much easier to design if you don't have to make it branch, and the code is much faster without the compiler inserting branches. People who work with floating point numbers every day care very deeply about performance.
If you don't care as much about performance, why not write your code in a language that does throw exceptions? Python, for example.
Those of us that do use numerics love NaN, love signed zeros, and can live with NaN ≠ NaN even though it's kind of dumb.
Edited to add: That said, I'd rather that 100 hours of computation be cut short than take longer and be equally useless...
What if you're doing some kind of matrix math and you just need the results of the diagonal and a single NaN creeps in somewhere but doesn't destroy your matrix. Would you accept your program needing 50% more LOC and taking 4x as long for this result?