Significantly improved error handling. Rather than panicking and crashing we should be propagating all errors up to python that reasonably can be. This should make the library significantly easier to call from python in future.