Our client code had a couple different error-handling approaches. Unfortunately, the Pennsylvania API itself _also_ has multiple approaches.
With this update, we simplify the outward exposure of Pennsylvania API errors as follows:
- All errors raised from `voter_tools.pa.client.*` derive from `voter_tools.APIError`.
- Some of those indicate special cases, like `InvalidAccessKeyError`, `ServiceUnavailableError`, and `TimeoutError`.
- One of those indicates bugs in the library itself (`ProgrammingError`) and should never be observed in practice once this library is mature/complete.
- The remaining and most important error type, `APIValidationError`, indicates that the API rejected a voter application request due to a validation error. It provides structured errors and an API _similar_ (but not exactly identical to) Pydantic's `ValidationError.errors()` and `.json()` methods.