Replace `sys.exit` calls with exceptions
I currently count 49 instances of sys.exit
of which I think all should instead raise an exception to give the caller a chance to handle the error rather than simply exiting the program. Unhandled exceptions will stop the program anyway.