Better Exception raising

It is generally bad practice to do `raise Exception` because it is non-descriptive of the error, and the programmer cannot handle the exception's type in isolation.

This patch:

- replaces all use of `raise Exception` with more concrete exception types
- fixes a few validation bugs
- adds 2 new exception types: `ImproperConfigurationError` and `DatabaseError`
- adds a number of tests for the above