1
+ 'use strict' ;
2
+
3
+ /**
4
+ * this module does a number of things:
5
+ * - first it overrides the built in angular exception handling, so that any exceptions that would normally be logged
6
+ * to the console, are POSTed via Ajax to a serverside service. It does the cross browser, by using stacktrace.js
7
+ * - second it exposes an applicationLoggingService that can be injected into any angular module. This service exposes
8
+ * and 'error' and 'debug' methods which if called will log to the console but also send those messages to a serverside
9
+ * service.
10
+ */
11
+ var loggingModule = angular . module ( 'talis.services.logging' , [ ] ) ;
12
+
13
+ /**
14
+ * Create a service that gives us a nice Angular-esque wrapper around the
15
+ * stackTrace.js pintStackTrace() method. We use a service because calling
16
+ * methods in the global context is not the 'angular way'
17
+ */
18
+ loggingModule . factory (
19
+ "stacktraceService" ,
20
+ function ( ) {
21
+ return ( {
22
+ print : printStackTrace
23
+ } ) ;
24
+ }
25
+ ) ;
26
+
27
+ /**
28
+ * Override Angular's built in exception handler, and tell it to use our new
29
+ * exceptionLoggingService
30
+ */
31
+ loggingModule . provider (
32
+ "$exceptionHandler" , {
33
+ $get : function ( exceptionLoggingService ) {
34
+ return ( exceptionLoggingService ) ;
35
+ }
36
+ }
37
+ ) ;
38
+
39
+ /**
40
+ * Exception Logging Service, currently only used by the $exceptionHandler
41
+ * but logs to the console and uses the stacktraceService to generate a browser independent stacktrace
42
+ * which is POSTed to server side clientlogging service.
43
+ */
44
+ loggingModule . factory (
45
+ "exceptionLoggingService" ,
46
+ [ "$log" , "$window" , "stacktraceService" , function ( $log , $window , stacktraceService ) {
47
+ function error ( exception , cause ) {
48
+
49
+ // preserver default behaviour i.e. dump to browser console
50
+ $log . error . apply ( $log , arguments ) ;
51
+
52
+ // now log server side.
53
+ try {
54
+ var errorMessage = exception . toString ( ) ;
55
+ var stackTrace = stacktraceService . print ( { e : exception } ) ;
56
+
57
+ // use AJAX not an angular service because if something has gone wrong
58
+ // angular might be fubar'd
59
+ $ . ajax ( {
60
+ type : "POST" ,
61
+ url : "/clientlogger" ,
62
+ contentType : "application/json" ,
63
+ data : angular . toJson ( {
64
+ url : $window . location . href ,
65
+ message : errorMessage ,
66
+ type : "exception" ,
67
+ stackTrace : stackTrace ,
68
+ cause : ( cause || "" )
69
+ } )
70
+ } ) ;
71
+ } catch ( loggingError ) {
72
+ $log . warn ( "Error logging failed" ) ;
73
+ $log . log ( loggingError ) ;
74
+ }
75
+ }
76
+ return ( error ) ;
77
+ } ]
78
+ ) ;
79
+
80
+ /**
81
+ * Application Logging Service added to give us a way of logging error / debug statements from the client to the server.
82
+ * For example a 502 gateway error on a http call wont thrown a browser exception, but we may want to have that logged on
83
+ * server specifically eg: $http.get().error( function(){ call applicationloggingservice here })
84
+ */
85
+ loggingModule . factory (
86
+ "applicationLoggingService" ,
87
+ [ "$log" , "$window" , function ( $log , $window ) {
88
+ return ( {
89
+ error : function ( message ) {
90
+ // preseve default behaviour
91
+ $log . error . apply ( $log , arguments ) ;
92
+ // send server side
93
+ $ . ajax ( {
94
+ type : "POST" ,
95
+ url : "/clientlogger" ,
96
+ contentType : "application/json" ,
97
+ data : angular . toJson ( {
98
+ url : $window . location . href ,
99
+ message : message ,
100
+ type : "error"
101
+ } )
102
+ } ) ;
103
+ } ,
104
+ debug : function ( message ) {
105
+ $log . log . apply ( $log , arguments ) ;
106
+ $ . ajax ( {
107
+ type : "POST" ,
108
+ url : "/clientlogger" ,
109
+ contentType : "application/json" ,
110
+ data : angular . toJson ( {
111
+ url : $window . location . href ,
112
+ message : message ,
113
+ type : "debug"
114
+ } )
115
+ } ) ;
116
+ }
117
+ } ) ;
118
+ } ]
119
+ ) ;
120
+
121
+ loggingModule . factory (
122
+ "userErrorReport" ,
123
+ [ '$window' , '$rootScope' , function ( $window , $rootScope ) {
124
+ return ( {
125
+ send : function ( userMessage , error ) {
126
+ var payload = {
127
+ url : $window . location . href ,
128
+ systemError : error ,
129
+ userMessage : userMessage
130
+ } ;
131
+ if ( $rootScope . user != null ) payload . user = $rootScope . user . profile ;
132
+ $ . ajax ( {
133
+ type : "POST" ,
134
+ url : "/usererrorreport" ,
135
+ contentType : "application/json" ,
136
+ data : angular . toJson ( payload )
137
+ } ) ;
138
+ }
139
+ } ) ;
140
+ } ]
141
+ ) ;
0 commit comments