├── .gitignore
├── .travis.yml
├── .jshintrc
├── bower.json
├── test
└── angular-raven_test.js
├── LICENSE
├── package.json
├── examples
└── index.html
├── Gruntfile.js
├── angular-raven.min.js
├── README.md
└── angular-raven.js
/.gitignore:
--------------------------------------------------------------------------------
1 | bower_components/
2 | node_modules/
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | - '0.8'
5 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "latedef": true,
6 | "newcap": true,
7 | "noarg": true,
8 | "sub": true,
9 | "undef": true,
10 | "unused": false,
11 | "boss": true,
12 | "eqnull": true,
13 | "node": true,
14 | "globals": {
15 | "window": false,
16 | "Raven": false,
17 | "document": false,
18 | "angular": false,
19 | "$": false,
20 | "_": false,
21 | "alert": false,
22 | "app": false
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-raven",
3 | "version": "0.6.3",
4 | "main": "angular-raven.js",
5 | "keywords": [
6 | "Patrick",
7 | "PatrickJS",
8 | "gdi2290",
9 | "angular",
10 | "angularjs",
11 | "angular.js",
12 | "$exceptionHandler",
13 | "raven",
14 | "ravenjs",
15 | "raven.js",
16 | "sentry.js",
17 | "sentry",
18 | "sentryjs",
19 | "error",
20 | "errorhandler"
21 | ],
22 | "authors": [
23 | {
24 | "name": "Patrick Stapleton",
25 | "email": "github@gdi2290.com",
26 | "url": "www.gdi2290.com"
27 | }
28 | ],
29 | "ignore": [
30 | "**/.*",
31 | "*.yml",
32 | "*.xml",
33 | "node_modules",
34 | "bower_components",
35 | "test",
36 | "tests"
37 | ],
38 | "dependencies": {
39 | "angular": "*",
40 | "raven-js": "*"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/angular-raven_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // var angularRaven = require('../angular-raven.js');
4 |
5 | /*
6 | ======== A Handy Little Nodeunit Reference ========
7 | https://github.com/caolan/nodeunit
8 |
9 | Test methods:
10 | test.expect(numAssertions)
11 | test.done()
12 | Test assertions:
13 | test.ok(value, [message])
14 | test.equal(actual, expected, [message])
15 | test.notEqual(actual, expected, [message])
16 | test.deepEqual(actual, expected, [message])
17 | test.notDeepEqual(actual, expected, [message])
18 | test.strictEqual(actual, expected, [message])
19 | test.notStrictEqual(actual, expected, [message])
20 | test.throws(block, [error], [message])
21 | test.doesNotThrow(block, [error], [message])
22 | test.ifError(value)
23 | */
24 |
25 | exports['angularRaven'] = {
26 | setUp: function(done) {
27 | // setup here
28 | done();
29 | },
30 | 'no args': function(test) {
31 | test.expect(1);
32 | // tests here
33 | test.equal(1, 1, 'pass the test.');
34 | test.done();
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2015 Patrick Stapleton, gdi2290, PatrickJS
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-raven",
3 | "version": "0.6.3",
4 | "main": "angular-raven.js",
5 | "description": "A Raven.js / Sentry wrapper for Angular.js",
6 | "homepage": "https://github.com/gdi2290/angular-raven",
7 | "bugs": "https://github.com/gdi2290/angular-raven/issues",
8 | "author": {
9 | "name": "Patrick Stapleton",
10 | "email": "github@gdi2290.com",
11 | "url": "www.gdi2290.com"
12 | },
13 | "keywords": [
14 | "Patrick",
15 | "PatrickJS",
16 | "gdi2290",
17 | "angular",
18 | "angularjs",
19 | "angular.js",
20 | "$exceptionHandler",
21 | "raven",
22 | "ravenjs",
23 | "raven.js",
24 | "sentry.js",
25 | "sentry",
26 | "sentryjs",
27 | "error",
28 | "errorhandler"
29 | ],
30 | "repository": {
31 | "type": "git",
32 | "url": "git@github.com:gdi2290/angular-raven.git"
33 | },
34 | "licenses": [
35 | {
36 | "type": "MIT"
37 | }
38 | ],
39 | "dependencies": {
40 | "angular": "*",
41 | "raven": "*"
42 | },
43 | "devDependencies": {
44 | "grunt": "~0.4.1",
45 | "grunt-bump": "^0.7.0",
46 | "grunt-contrib-jshint": "~0.6.0",
47 | "grunt-contrib-nodeunit": "~0.2.0",
48 | "grunt-contrib-uglify": "~0.9.0",
49 | "grunt-contrib-watch": "~0.5.0",
50 | "load-grunt-tasks": "~0.1.0",
51 | "time-grunt": "~0.1.0"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Raven.js for Angular.js
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 | -
21 |
{{ err.stack }}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 |
5 | require('load-grunt-tasks')(grunt);
6 | require('time-grunt')(grunt);
7 |
8 | // Project configuration.
9 | grunt.initConfig({
10 | nodeunit: {
11 | files: ['test/**/*_test.js'],
12 | },
13 | jshint: {
14 | options: {
15 | jshintrc: '.jshintrc',
16 | },
17 | gruntfile: {
18 | src: 'Gruntfile.js',
19 | },
20 | lib: {
21 | src: ['angular-raven.js'],
22 | },
23 | test: {
24 | src: ['test/**/*.js'],
25 | },
26 | },
27 | watch: {
28 | gruntfile: {
29 | files: '<%= jshint.gruntfile.src %>',
30 | tasks: ['jshint:gruntfile'],
31 | },
32 | lib: {
33 | files: '<%= jshint.lib.src %>',
34 | tasks: ['jshint:lib', 'nodeunit'],
35 | },
36 | test: {
37 | files: '<%= jshint.test.src %>',
38 | tasks: ['jshint:test', 'nodeunit'],
39 | },
40 | },
41 | uglify: {
42 | options: {
43 | compress: true,
44 | mangle: true,
45 | },
46 | dist: {
47 | files: {
48 | 'angular-raven.min.js': ['angular-raven.js'],
49 | },
50 | },
51 | },
52 | bump: {
53 | options: {
54 | files: ['package.json', 'bower.json'],
55 | updateConfigs: [],
56 | commit: true,
57 | commitMessage: 'Release v%VERSION%',
58 | commitFiles: ['package.json', 'bower.json'],
59 | createTag: true,
60 | tagName: 'v%VERSION%',
61 | tagMessage: 'Version %VERSION%',
62 | push: false,
63 | pushTo: 'origin',
64 | gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
65 | globalReplace: false,
66 | prereleaseName: false,
67 | regExp: false,
68 | },
69 | },
70 | });
71 |
72 | // Default task.
73 | grunt.registerTask('default', [
74 | 'jshint',
75 | 'nodeunit',
76 | 'uglify',
77 | ]);
78 |
79 | };
80 |
--------------------------------------------------------------------------------
/angular-raven.min.js:
--------------------------------------------------------------------------------
1 | !function(a,b,c){"use strict";function d(){this.development=function(a){return g=a||g,this},this.$get=["$window","$log",function(a,d){var e={VERSION:a.Raven?a.Raven.VERSION:"development",TraceKit:a.Raven?a.Raven.TraceKit:"development",captureException:function(b,c){g?d.error("Raven: Exception ",b,c):a.Raven.captureException(b,c)},captureMessage:function(b,c){g?d.error("Raven: Message ",b,c):a.Raven.captureMessage(b,c)},setUser:function(b){g?d.info("Raven: User ",b):a.Raven.setUser?a.Raven.setUser(b):a.Raven.setUserContext&&a.Raven.setUserContext(b)},setUserContext:function(b){g?d.info("Raven: User ",b):a.Raven.setUserContext?a.Raven.setUserContext(b):a.Raven.setUser&&a.Raven.setUser(b)},lastException:function(){g?d.error("Raven: Last Exception"):a.Raven.lastException()},setExtraContext:function(b){g?d.info("Raven: Extra Context ",b):a.Raven.setExtraContext(b)},setRelease:function(b){g?d.info("Raven: Release Context ",b):a.Raven.setRelease(b)},isSetup:function(){return a.Raven.isSetup()},setDataCallback:function(b){return a.Raven.setDataCallback(b)},setShouldSendCallback:function(b){return a.Raven.setShouldSendCallback(b)},setTagsContext:function(b){g?d.info("Raven: Tags Context ",b):a.Raven.setTagsContext(b)},context:function(a,d,e){var f=this;return b.isFunction(a)&&(e=d||[],d=a,a=c),f.wrap(a,d).apply(f,e)},wrap:function(a,d){function e(){for(var b=[],c=arguments.length;c--;)b[c]=f.wrap(a,arguments[c]);try{return d.apply(this,b)}catch(e){f.captureException(e,a)}}var f=this;if(b.isUndefined(d)&&!b.isFunction(a))return a;if(b.isFunction(a)&&(d=a,a=c),!b.isFunction(d))return d;if(d.__raven__)return d;for(var g in d)d.hasOwnProperty(g)&&(e[g]=d[g]);return e.__raven__=!0,e}};return e}]}function e(a){a.decorator("$exceptionHandler",["$delegate","$raven","$injector",f])}function f(a,c,d){function e(e,g){f=f||d.get("$location");var h={culprit:f.absUrl(),extra:{exception:e,cause:g}};if(e instanceof Error)c.captureException(e,h);else{var i="";i=b.isString(e.message)?e.message:b.isString(e)?e:e.statusText||"",c.captureMessage(i,h)}a(e,g)}var f;return e}var g=null;b.module("ngRaven",[]).provider("$raven",d).provider("Raven",d).config(["$provide",e]),b.module("angular-raven",["ngRaven"])}(this,angular);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-raven [](https://travis-ci.org/gdi2290/angular-raven)
2 | A Raven.js / Sentry wrapper for Angular.js
3 |
4 | #How do I add this to my project?
5 |
6 | You can download angular-raven by:
7 |
8 | * (prefered) Using bower and running `bower install angular-raven --save`
9 | * Using npm and running `npm install angular-raven --save`
10 | * Downloading it manually by clicking [here to download development unminified version](https://raw.github.com/gdi2290/angular-raven/master/angular-raven.js)
11 |
12 |
13 | ````html
14 |
15 | Log Error
16 |
17 |
18 |
19 |
29 |
30 |
31 |
48 |
49 | ````
50 |
51 | Initializing Raven.js outside of Angular allows Raven to track errors when Angular wasn't able to bootstrap correctly.
52 |
53 |
54 | The community has compiled a list of common ignore rules for common things, like Facebook, Chrome extensions, etc.
55 | ```javascript
56 | Raven.config('YOUR_PUBLIC_DSN', {
57 | logger: 'javascript',
58 | ignoreErrors: [
59 | // Random plugins/extensions
60 | 'top.GLOBALS',
61 | // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error. html
62 | 'originalCreateNotification',
63 | 'canvas.contentDocument',
64 | 'MyApp_RemoveAllHighlights',
65 | 'http://tt.epicplay.com',
66 | 'Can\'t find variable: ZiteReader',
67 | 'jigsaw is not defined',
68 | 'ComboSearch is not defined',
69 | 'http://loading.retry.widdit.com/',
70 | 'atomicFindClose',
71 | // Facebook borked
72 | 'fb_xd_fragment',
73 | // ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha)
74 | // See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy
75 | 'bmi_SafeAddOnload',
76 | 'EBCallBackMessageReceived',
77 | // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx
78 | 'conduitPage'
79 | ],
80 | ignoreUrls: [
81 | // Facebook flakiness
82 | /graph\.facebook\.com/i,
83 | // Facebook blocked
84 | /connect\.facebook\.net\/en_US\/all\.js/i,
85 | // Woopra flakiness
86 | /eatdifferent\.com\.woopra-ns\.com/i,
87 | /static\.woopra\.com\/js\/woopra\.js/i,
88 | // Chrome extensions
89 | /extensions\//i,
90 | /^chrome:\/\//i,
91 | // Other plugins
92 | /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
93 | /webappstoolbarba\.texthelp\.com\//i,
94 | /metrics\.itunes\.apple\.com\.edgesuite\.net\//i
95 | ]
96 | }).install();
97 |
--------------------------------------------------------------------------------
/angular-raven.js:
--------------------------------------------------------------------------------
1 | (function(global, angular, undefined) {
2 | 'use strict';
3 |
4 | var _development = null;
5 |
6 | function $RavenProvider() {
7 |
8 | this.development = function(config) {
9 | _development = config || _development;
10 | return this;
11 | };
12 |
13 | this.$get = ['$window', '$log', function($window, $log) {
14 | var service = {
15 | VERSION: ($window.Raven) ? $window.Raven.VERSION : 'development',
16 | TraceKit: ($window.Raven) ? $window.Raven.TraceKit : 'development',
17 | captureException: function captureException(exception, cause) {
18 | if (!_development) {
19 | $window.Raven.captureException(exception, cause);
20 | } else {
21 | $log.error('Raven: Exception ', exception, cause);
22 | }
23 | },
24 | captureMessage: function captureMessage(message, data) {
25 | if (!_development) {
26 | $window.Raven.captureMessage(message, data);
27 | } else {
28 | $log.error('Raven: Message ', message, data);
29 | }
30 | },
31 | setUser: function setUser(user) {
32 | if (_development) {
33 | $log.info('Raven: User ', user);
34 | } else {
35 | if ($window.Raven.setUser) {
36 | $window.Raven.setUser(user);
37 | } else if ($window.Raven.setUserContext) {
38 | $window.Raven.setUserContext(user);
39 | }
40 | }
41 | },
42 | setUserContext: function setUserContext(user) {
43 | if (_development) {
44 | $log.info('Raven: User ', user);
45 | } else {
46 | if ($window.Raven.setUserContext) {
47 | $window.Raven.setUserContext(user);
48 | } else if ($window.Raven.setUser) {
49 | $window.Raven.setUser(user);
50 | }
51 | }
52 | },
53 | lastException: function lastException() {
54 | if (_development) {
55 | $log.error('Raven: Last Exception');
56 | } else {
57 | $window.Raven.lastException();
58 | }
59 | },
60 | setExtraContext: function setExtraContext(data) {
61 | if (_development) {
62 | $log.info('Raven: Extra Context ', data);
63 | } else {
64 | $window.Raven.setExtraContext(data);
65 | }
66 | },
67 | setRelease: function setRelease(data) {
68 | if (_development) {
69 | $log.info('Raven: Release Context ', data);
70 | } else {
71 | $window.Raven.setRelease(data);
72 | }
73 | },
74 | isSetup: function isSetup() {
75 | return $window.Raven.isSetup();
76 | },
77 | setDataCallback: function setDataCallback(callback) {
78 | return $window.Raven.setDataCallback(callback);
79 | },
80 | setShouldSendCallback: function setShouldSendCallback(callback) {
81 | return $window.Raven.setShouldSendCallback(callback);
82 | },
83 | setTagsContext: function setTagsContext(data) {
84 | if (_development) {
85 | $log.info('Raven: Tags Context ', data);
86 | } else {
87 | $window.Raven.setTagsContext(data);
88 | }
89 | },
90 | context: function context(options, func, args) {
91 | var RavenService = this;
92 |
93 | if (angular.isFunction(options)) {
94 | args = func || [];
95 | func = options;
96 | options = undefined;
97 | }
98 |
99 | return RavenService.wrap(options, func).apply(RavenService, args);
100 | },
101 | wrap: function wrap(options, func) {
102 | var RavenService = this;
103 |
104 | if (angular.isUndefined(func) && !angular.isFunction(options)) {
105 | return options;
106 | }
107 |
108 | if (angular.isFunction(options)) {
109 | func = options;
110 | options = undefined;
111 | }
112 |
113 | if (!angular.isFunction(func)) {
114 | return func;
115 | }
116 |
117 | if (func.__raven__) {
118 | return func;
119 | }
120 |
121 | function Wrapped() {
122 | var args = [], i = arguments.length;
123 | while (i--) {
124 | args[i] = RavenService.wrap(options, arguments[i]);
125 | }
126 | try {
127 | return func.apply(this, args);
128 | } catch (e) {
129 | RavenService.captureException(e, options);
130 | }
131 | }
132 |
133 | for (var property in func) {
134 | if (func.hasOwnProperty(property)) {
135 | Wrapped[property] = func[property];
136 | }
137 | }
138 | Wrapped.__raven__ = true;
139 | return Wrapped;
140 | }
141 |
142 | };
143 |
144 | return service;
145 | }]; // end $get
146 | } // end provider
147 |
148 | function $ExceptionHandlerProvider($provide) {
149 | $provide.decorator('$exceptionHandler', [
150 | '$delegate', '$raven', '$injector',
151 | $ExceptionHandlerDecorator
152 | ]);
153 | }
154 |
155 | function $ExceptionHandlerDecorator($delegate, $raven, $injector) {
156 | // If we try to include a $location object, we will get:
157 | // "Circular dependency found: $location <- $exceptionHandler <- $rootScope"
158 | // Therefore, we inject it.
159 | var $location;
160 |
161 | function $ExceptionHandler(exception, cause) {
162 | $location = $location || $injector.get('$location');
163 |
164 | var exceptionData = {
165 | culprit: $location.absUrl(),
166 | extra: {
167 | exception: exception,
168 | cause: cause
169 | }
170 | };
171 |
172 | if (exception instanceof Error) {
173 | $raven.captureException(exception, exceptionData);
174 | } else {
175 | var message = '';
176 | if (angular.isString(exception.message)) {
177 | message = exception.message;
178 | } else {
179 | message = angular.isString(exception) ? exception : exception.statusText || '';
180 | }
181 | $raven.captureMessage(message, exceptionData);
182 | }
183 |
184 | $delegate(exception, cause);
185 | }
186 |
187 | return $ExceptionHandler;
188 | }
189 |
190 | angular.module('ngRaven', [])
191 | .provider('$raven', $RavenProvider)
192 | .provider('Raven', $RavenProvider)
193 | .config(['$provide', $ExceptionHandlerProvider]);
194 |
195 | angular.module('angular-raven', ['ngRaven']);
196 |
197 | }(this, angular));
198 |
--------------------------------------------------------------------------------