Replace `Box<dyn Error + Send + Sync>` with a real Error type
Using Box<dyn Error + Send + Sync>
makes it difficult to build early returns reasonably, if we used a custom error type that can be converted into from various other error types we'd probably have less trouble with type inference.