catch errors and exceptions in promises

This is a moderate refactor that does a few things:

* Most `IDBRequest`s are now proxied through an internal method called
promiseRequest.  This method attaches standard success/error handlers to
each request, and also catches any exceptions.

* Operations that can iterate over arrays can be easily passed into
promiseRequest via the spreadRequest convenience method (which
internally relies on `$q.all`)

* Calls to `$rootScope.apply()` are wrapped in a convenience method.