>>> (-1) ** 0.5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: negative number cannot be raised to a fractional power
Any conforming implementation of Python 2.7 must raise ValueError. Why define it? So that a programmer can catch ValueError.
As I said in another thread, trusting a buggy program to debug itself is futile. Effectively handling unintentional ValueError (or IndexError, TypeError) is not practically possible. For one, there's a good chance the program's persistent shared state is in an inconsistent state when those unintentional exceptions happen. Better to just abort().
They can choose to do just that. But they're also afforded a little more flexibility with this approach. A developer could use this to serve up a stack trace rather than just crashing the server, for example.
You can always restart the process after an abort(). Continuing to run a server with persistent in-process state after an unexpected exception is dangerous and you risk corrupting data.
Many servers do not have persistent in-process state, or have in-process state that is robust against bugs in other parts of the program. In particular, in most languages where you need special syntax or data types to access shared state (so, definitely not C or C++, but Python should count), you can isolate all the code that doesn't use this syntax or these types of objects inside a giant try/catch, and know that any misbehavior inside that block of code cannot possibly have affected the shared state.
This is not scalable. A production server might import code from dozens, if not hundreds of modules, all of which have varying degrees of code quality and are written by different authors from different organizations. It's not practical to trust that all the code is written in a way that is exception-safe. Try:catch:log:continue is a hazard and signal that the person who wrote the code hasn't thought very deeply about correctness.