Companion material with this blog post. The source code is available on GitHub: https://github.com/pavadeli/angularjs-errorhandling.
Error messages will appear in the top-left corner of the browser screen. Not very user-friendly, I know, but now you don't have to scroll to the top to see the error messages. See the blog post for more information.
Synchronous error (unhandled)A function throws a synchronous error. undecoratedService.throwsAnError();Look in the console log for the error details. User doesn't know anything went wrong. |
|
Synchronous error (manual handling)Add the error message to the list of errors manually. try { undecoratedService.throwsAnError(); } catch (err) { errorHandler.errors.push(err && err.message || err); } |
|
Synchronous error (manual function wrapping)Call the service using the errorHandler (kinda stupid). errorHandler.call(undecoratedService.throwsAnError, undecoratedService); |
|
Asynchronous error (unhandled)A function returns a promise which gets rejected after some time. undecoratedService.promiseRejects();Error gets lost. User doesn't know anything went wrong. |
|
Asynchronous error (manual handling)Add the error message to the list of errors manually. undecoratedService.promiseRejects() ['catch'](function (err) { errorHandler.errors.push(err); }); |
|
Asynchronous error (manual function wrapping)Call the service using the errorHandler (stupid). errorHandler.call(undecoratedService.promiseRejects, undecoratedService); |
Synchronous error (automatic function wrapping)Call the service as you normally would but get error messages for free. decoratedService.throwsAnError(); |
|
Asynchronous error (automatic function wrapping)Call the service as you normally would but get error messages for free. decoratedService.promiseRejectsAfterAWhile(); |
This is a more realistic scenario. Suppose you want to load some data "ajaxy" on the press of a button, you want the code to look like this:
function loadData() { return $http.get('somefile.html') .then(function (result) { return result.data; }); }
$scope.data = ''; $scope.buttonPressed = function () { exampleService.loadData().then(function (data) { $scope.data = data; }); };
It is obvious that any error will leave the user in the dark about what happened, without any feedback. We do want to inform the user about the error with a meaningful error message, but we don't want to write tedious error handling code over and over again. Now with the following simple command, we get just that:
errorHandlerProvider.decorate($provide, ['theServiceNameHere', 'anotherServiceHere']);
Data: {{data}}