Skip to content

Commit 892008a

Browse files
authored
Add Vue.js (2.0) plugin (#688)
1 parent 2f6b99a commit 892008a

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

docs/integrations/vue.rst

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
Vue.js (2.0)
2+
============
3+
4+
.. sentry:support-warning::
5+
6+
This plugin only works with Vue 2.0 or greater.
7+
8+
9+
To use Sentry with your Vue application, you will need to use both Raven.js (Sentry's browser JavaScript SDK) and the Raven.js Vue plugin.
10+
11+
On its own, Raven.js will report any uncaught exceptions triggered from your application. For advanced usage examples of Raven.js, please read :doc:`Raven.js usage <../usage>`.
12+
13+
Additionally, the Raven.js Vue plugin will capture the name and props state of the active component where the error was thrown. This is reported via Vue's `config.errorHandler` hook.
14+
15+
Installation
16+
------------
17+
18+
Raven.js and the Raven.js Vue plugin are distributed using a few different methods.
19+
20+
Using our CDN
21+
~~~~~~~~~~~~~
22+
23+
For convenience, our CDN serves a single, minified JavaScript file containing both Raven.js and the Raven.js Vue plugin. It should be included **after** Vue, but **before** your application code.
24+
25+
Example:
26+
27+
.. sourcecode:: html
28+
29+
<script src="https://cdn.jsdelivr.net/vue/2.0.0-rc/vue.min.js"></script>
30+
<script src="https://cdn.ravenjs.com/3.4.1/vue/raven.min.js"></script>
31+
<script>Raven.config('___PUBLIC_DSN___').install();</script>
32+
33+
Note that this CDN build auto-initializes the Vue plugin.
34+
35+
Using package managers
36+
~~~~~~~~~~~~~~~~~~~~~~
37+
38+
Both Raven.js and the Raven.js Vue plugin can be installed via npm and Bower.
39+
40+
npm
41+
````
42+
43+
.. code-block:: sh
44+
45+
$ npm install raven-js --save
46+
47+
48+
Bower
49+
`````
50+
51+
.. code-block:: sh
52+
53+
$ bower install raven-js --save
54+
55+
In your main application file, import and configure both Raven.js and the Raven.js Vue plugin as follows:
56+
57+
.. code-block:: js
58+
59+
import Raven from 'raven-js';
60+
import RavenVue from 'raven-js/plugins/vue';
61+
62+
Raven
63+
.config('___PUBLIC_DSN___')
64+
.addPlugin(RavenVue)
65+
.install();

plugins/vue.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Vue.js 2.0 plugin
3+
*
4+
*/
5+
'use strict';
6+
7+
function vuePlugin(Raven, Vue) {
8+
Vue = Vue || window.Vue;
9+
10+
// quit if Vue isn't on the page
11+
if (!Vue || !Vue.config) return;
12+
13+
var _oldOnError = Vue.config.errorHandler;
14+
Vue.config.errorHandler = function VueErrorHandler(error, vm) {
15+
Raven.captureException(error, {
16+
extra: {
17+
componentName: Vue.util.formatComponentName(vm),
18+
propsData: vm.$options.propsData
19+
}
20+
});
21+
22+
if (typeof _oldOnError === 'function') {
23+
_oldOnError.call(this, error, vm);
24+
}
25+
};
26+
}
27+
28+
module.exports = vuePlugin;
29+

test/plugins/vue.test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
var _Raven = require('../../src/raven');
2+
var vuePlugin = require('../../plugins/vue');
3+
4+
var Raven;
5+
describe('Vue plugin', function () {
6+
beforeEach(function () {
7+
Raven = new _Raven();
8+
Raven.config('http://abc@example.com:80/2');
9+
});
10+
11+
describe('errorHandler', function () {
12+
beforeEach(function () {
13+
this.sinon.stub(Raven, 'captureException');
14+
this.MockVue = {
15+
config: {},
16+
util: {
17+
formatComponentName: function() {
18+
return '<root component>'
19+
}
20+
}
21+
};
22+
});
23+
24+
it('should capture component name and propsData', function () {
25+
vuePlugin(Raven, this.MockVue);
26+
27+
this.MockVue.config.errorHandler(new Error('foo'), {
28+
$options: {
29+
propsData: {
30+
foo: 'bar'
31+
}
32+
}
33+
}, {} /* vm */);
34+
35+
assert.isTrue(Raven.captureException.calledOnce);
36+
37+
assert.deepEqual(Raven.captureException.args[0][1].extra, {
38+
propsData: {
39+
foo: 'bar'
40+
},
41+
componentName: '<root component>'
42+
});
43+
});
44+
45+
it('should call the existing error handler', function () {
46+
var errorHandler = this.sinon.stub();
47+
this.MockVue.config.errorHandler = errorHandler;
48+
vuePlugin(Raven, this.MockVue); // should override errorHandler
49+
50+
var err = new Error('foo');
51+
var vm = {
52+
$options: { propsData: {} }
53+
};
54+
this.MockVue.config.errorHandler(err, vm);
55+
56+
assert.isTrue(Raven.captureException.calledOnce);
57+
assert.isTrue(errorHandler.calledOnce);
58+
assert.equal(errorHandler.args[0][0], err);
59+
assert.equal(errorHandler.args[0][1], vm);
60+
});
61+
});
62+
});

0 commit comments

Comments
 (0)