Better handling of promise errors in runner

- Use a separate `catch` rather than an error callback for the
  `tunnel.start` callback.
- Refactor the `tunnel.start` catch, the `main.run` otherwise, and the
  uncaughtException handler to use a shared handler function.

refs #254, #292