Error logging (server side) for AngularJS

When you have a production application written in AngularJS it sometimes happens that the javascript-code has bugs (gosh!).

Usually you don’t know about these (if your unit tests won’t catch them) until your users start to complain about things not working.

So – what to do?

  • Ask your users to “Open javascript console and cut and paste the log to email”?
  • Ask spesific guestions “Where error happens, what did you do? What data were you editing?” and test yourself
  • Log errors automatically to serverside and harvest user interface exceptions

Automatic error logging from AngularJS to server side

So how to catch unhandled javascript errors in AngularJS?

Add an excption handler to your application

//
// Enhance the application by adding custom exception handler
// - Catch unhandled errors
//
angular.module('app').provider(
        "$exceptionHandler",
        {
            $get: function(errorLogService) {
                console.log("$exceptionHandler.$get()");
                return(errorLogService);
            }
        }
);

In the previous code you are creating provider for

$exceptionHandler

– there you will return your exception handler

errorLogService

.

What the hell is the “errorLogService”?

It’s the factory that will provider your error logger: (example 2 in github)

//
// Factory to provider error log service
// - simple console logger
//
angular.module('app').factory(
        "errorLogService",
        function($log, $window) {

            $log.info("errorLogService()");

            function log(exception, cause) {
                $log.debug("errorLogService.log()");

                // Default behavior, log to browser console
                $log.error.apply($log, arguments);

                logErrorToServerSide(exception, cause);
            }

            function logErrorToServerSide(exception, cause) {
                $log.info("logErrorToServerSide()... NOT IMPLEMENTED");
            }

            // Return the logging function.
            return(log);            
        });

An example how to actually log errors to server side

The following is an example of how to log errors to server side.

I am using jQuery to POST the errors as JSON to server side handler. (see example 3 in github)

//
// Factory to provider error log service
// - log errors to server side
//
angular.module('app').factory(
        "errorLogService",
        function($log, $window) {

            $log.info("errorLogService()");

            function log(exception, cause) {
                $log.debug("errorLogService.log()");

                // Default behavior, log to browser console
                $log.error.apply($log, arguments);

                logErrorToServerSide(exception, cause);
            }

            function logErrorToServerSide(exception, cause) {
                $log.info("logErrorToServerSide()");

                // Read from configuration
                var serviceUrl = "http://localhost:3000/error";

                // Try to send stacktrace event to server
                try {
                    $log.debug("logging error to server side: serviceUrl = " + serviceUrl);

                    // Not sure how portable this actually is
                    var errorMessage = exception ? exception.toString() : "no exception";
                    var stackTrace = exception ? (exception.stack ? exception.stack.toString() : "no stack") : "no exception";
                    var browserInfo = {
                        navigatorAppName : navigator.appName,
                        navigatorUserAgent : navigator.userAgent
                    };

                    // This is the custom error content you send to server side
                    var data = angular.toJson({
                        errorUrl: $window.location.href,
                        errorMessage: errorMessage,
                        stackTrace: stackTrace,
                        cause: (cause || "no cause"),
                        browserInfo: browserInfo
                    });

                    $log.debug("logging error to server side...", data);

                    // Log the JavaScript error to the server.
                    $.ajax({
                        type: "POST",
                        url: serviceUrl,
                        contentType: "application/json",
                        xhrFields: {
                            withCredentials: true
                        },
                        data: data
                    });

                } catch (loggingError) {
                    // For Developers - log the logging-failure.
                    $log.warn("Error logging to server side failed");
                    $log.log(loggingError);
                }
            }

            // And return the logging function
            return(log);            
        });

If you really want to see the sever side output, you can start the included simple nodejs / express web server that will log the error to console.

    cd error_logging_server
    npm install
    node index.js

Example in github

https://github.com/Team2Oy/blog-angular-exception-logging

Other things to consider

If you get too much and same errors from UI:

  • Inspect and identify same errors / locations in client javascript and log only once
  • Do the error aggregation on server side
  • Write unit tests 🙂

Standard disclaimer

Use freely at your own risk.

Advertisements