Add custom TimeoutException

This relieves us from wrapping java.util.concurrent.TimeoutException in
an unchecked exception and also allows for more specific exception
messages.