@strapi/plugin-sentry 4.0.0-next.6 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -7
- package/admin/src/index.js +0 -8
- package/package.json +18 -12
- package/server/bootstrap.js +8 -0
- package/server/config.js +10 -0
- package/server/index.js +11 -0
- package/server/middlewares/sentry.js +40 -0
- package/{services → server/services}/__tests__/sentry.test.js +12 -18
- package/server/services/index.js +7 -0
- package/{services/sentry.js → server/services/sentry/index.js} +5 -9
- package/strapi-admin.js +3 -0
- package/strapi-server.js +3 -0
- package/admin/src/assets/images/logo.svg +0 -1
- package/config/functions/bootstrap.js +0 -7
- package/config/routes.json +0 -3
- package/config/settings.json +0 -5
- package/controllers/sentry.js +0 -9
- package/middlewares/sentry/defaults.json +0 -5
- package/middlewares/sentry/index.js +0 -33
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ module.exports = ({ env }) => ({
|
|
|
49
49
|
You can access a Sentry service throughout your app.
|
|
50
50
|
|
|
51
51
|
```js
|
|
52
|
-
const sentryService = strapi.
|
|
52
|
+
const sentryService = strapi.plugin('sentry').service('sentry');
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
This service exposes the following methods:
|
|
@@ -65,13 +65,19 @@ try {
|
|
|
65
65
|
// Your code here
|
|
66
66
|
} catch (error) {
|
|
67
67
|
// Either send a simple error
|
|
68
|
-
strapi
|
|
68
|
+
strapi
|
|
69
|
+
.plugin('sentry')
|
|
70
|
+
.service('sentry')
|
|
71
|
+
.sendError(error);
|
|
69
72
|
|
|
70
73
|
// Or send an error with a customized Sentry scope
|
|
71
|
-
strapi
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
strapi
|
|
75
|
+
.plugin('sentry')
|
|
76
|
+
.service('sentry')
|
|
77
|
+
.sendError(error, (scope, sentryInstance) => {
|
|
78
|
+
// Customize the scope here
|
|
79
|
+
scope.setTag('my_custom_tag', 'Tag value');
|
|
80
|
+
});
|
|
75
81
|
throw error;
|
|
76
82
|
}
|
|
77
83
|
```
|
|
@@ -83,7 +89,10 @@ Use it if you need direct access to the Sentry instance, which should already al
|
|
|
83
89
|
**Example**
|
|
84
90
|
|
|
85
91
|
```js
|
|
86
|
-
const sentryInstance = strapi
|
|
92
|
+
const sentryInstance = strapi
|
|
93
|
+
.plugin('sentry')
|
|
94
|
+
.service('sentry')
|
|
95
|
+
.getInstance();
|
|
87
96
|
```
|
|
88
97
|
|
|
89
98
|
## Disabling
|
package/admin/src/index.js
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
|
2
2
|
import pluginPkg from '../../package.json';
|
|
3
3
|
import pluginId from './pluginId';
|
|
4
|
-
import pluginLogo from './assets/images/logo.svg';
|
|
5
4
|
|
|
6
|
-
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
|
7
|
-
const icon = pluginPkg.strapi.icon;
|
|
8
5
|
const name = pluginPkg.strapi.name;
|
|
9
6
|
|
|
10
7
|
export default {
|
|
11
8
|
register(app) {
|
|
12
9
|
app.registerPlugin({
|
|
13
|
-
description: pluginDescription,
|
|
14
|
-
icon,
|
|
15
10
|
id: pluginId,
|
|
16
|
-
isReady: true,
|
|
17
|
-
isRequired: pluginPkg.strapi.required || false,
|
|
18
11
|
name,
|
|
19
|
-
pluginLogo,
|
|
20
12
|
});
|
|
21
13
|
},
|
|
22
14
|
bootstrap() {},
|
package/package.json
CHANGED
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/plugin-sentry",
|
|
3
|
-
"version": "4.0.0
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Send Strapi error events to Sentry",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"@sentry/node": "6.7.1"
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/strapi/strapi.git",
|
|
8
|
+
"directory": "packages/plugins/sentry"
|
|
12
9
|
},
|
|
10
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
13
11
|
"author": {
|
|
14
|
-
"name": "Strapi
|
|
12
|
+
"name": "Strapi Solutions SAS",
|
|
15
13
|
"email": "hi@strapi.io",
|
|
16
14
|
"url": "https://strapi.io"
|
|
17
15
|
},
|
|
18
16
|
"maintainers": [
|
|
19
17
|
{
|
|
20
|
-
"name": "Strapi
|
|
18
|
+
"name": "Strapi Solutions SAS",
|
|
21
19
|
"email": "hi@strapi.io",
|
|
22
20
|
"url": "https://strapi.io"
|
|
23
21
|
}
|
|
24
22
|
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@sentry/node": "6.7.1"
|
|
25
|
+
},
|
|
25
26
|
"engines": {
|
|
26
27
|
"node": ">=12.x.x <=16.x.x",
|
|
27
28
|
"npm": ">=6.0.0"
|
|
28
29
|
},
|
|
29
|
-
"
|
|
30
|
-
|
|
30
|
+
"strapi": {
|
|
31
|
+
"name": "sentry",
|
|
32
|
+
"displayName": "Sentry",
|
|
33
|
+
"description": "Send Strapi error events to Sentry.",
|
|
34
|
+
"kind": "plugin"
|
|
35
|
+
},
|
|
36
|
+
"gitHead": "b181702f0202b2c6d645d42b195a831f25cd0b03"
|
|
31
37
|
}
|
package/server/config.js
ADDED
package/server/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Programmatic sentry middleware. We do not want to expose it in the plugin
|
|
5
|
+
* @param {{ strapi: import('@strapi/strapi').Strapi }}
|
|
6
|
+
*/
|
|
7
|
+
module.exports = ({ strapi }) => {
|
|
8
|
+
const sentryService = strapi.plugin('sentry').service('sentry');
|
|
9
|
+
sentryService.init();
|
|
10
|
+
const sentry = sentryService.getInstance();
|
|
11
|
+
|
|
12
|
+
if (!sentry) {
|
|
13
|
+
// initialization failed
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
strapi.server.use(async (ctx, next) => {
|
|
18
|
+
try {
|
|
19
|
+
await next();
|
|
20
|
+
} catch (error) {
|
|
21
|
+
sentry.sendError(error, (scope, sentryInstance) => {
|
|
22
|
+
scope.addEventProcessor(event => {
|
|
23
|
+
// Parse Koa context to add error metadata
|
|
24
|
+
return sentryInstance.Handlers.parseRequest(event, ctx.request, {
|
|
25
|
+
// Don't parse the transaction name, we'll do it manually
|
|
26
|
+
transaction: false,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Manually add transaction name
|
|
31
|
+
scope.setTag('transaction', `${ctx.method} ${ctx.request.url}`);
|
|
32
|
+
// Manually add Strapi version
|
|
33
|
+
scope.setTag('strapi_version', strapi.config.info.strapi);
|
|
34
|
+
scope.setTag('method', ctx.method);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -19,25 +19,21 @@ jest.mock('@sentry/node', () => {
|
|
|
19
19
|
};
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
const defaultConfig = require('../../config
|
|
22
|
+
const sentryServiceLoader = require('../sentry');
|
|
23
|
+
const defaultConfig = require('../../config').default;
|
|
24
24
|
|
|
25
25
|
describe('Sentry service', () => {
|
|
26
26
|
beforeEach(() => {
|
|
27
27
|
// Reset Strapi state
|
|
28
28
|
global.strapi = {
|
|
29
|
-
config: {
|
|
30
|
-
|
|
31
|
-
sentry: {
|
|
32
|
-
config: defaultConfig,
|
|
33
|
-
},
|
|
29
|
+
config: {
|
|
30
|
+
get: () => defaultConfig,
|
|
34
31
|
},
|
|
35
32
|
log: {
|
|
36
33
|
warn: jest.fn(),
|
|
37
34
|
info: jest.fn(),
|
|
38
35
|
},
|
|
39
36
|
};
|
|
40
|
-
sentryService = require('../sentry');
|
|
41
37
|
});
|
|
42
38
|
|
|
43
39
|
afterEach(() => {
|
|
@@ -46,6 +42,7 @@ describe('Sentry service', () => {
|
|
|
46
42
|
});
|
|
47
43
|
|
|
48
44
|
it('disables Sentry when no DSN is provided', () => {
|
|
45
|
+
const sentryService = sentryServiceLoader({ strapi });
|
|
49
46
|
sentryService.init();
|
|
50
47
|
expect(strapi.log.info).toHaveBeenCalledWith(expect.stringMatching(/disabled/i));
|
|
51
48
|
|
|
@@ -54,9 +51,8 @@ describe('Sentry service', () => {
|
|
|
54
51
|
});
|
|
55
52
|
|
|
56
53
|
it('disables Sentry when an invalid DSN is provided', () => {
|
|
57
|
-
global.strapi.
|
|
58
|
-
|
|
59
|
-
};
|
|
54
|
+
global.strapi.config.get = () => ({ dsn: INVALID_DSN });
|
|
55
|
+
const sentryService = sentryServiceLoader({ strapi });
|
|
60
56
|
sentryService.init();
|
|
61
57
|
expect(strapi.log.warn).toHaveBeenCalledWith(expect.stringMatching(/could not set up sentry/i));
|
|
62
58
|
|
|
@@ -65,14 +61,14 @@ describe('Sentry service', () => {
|
|
|
65
61
|
});
|
|
66
62
|
|
|
67
63
|
it("doesn't send events before init", () => {
|
|
64
|
+
const sentryService = sentryServiceLoader({ strapi });
|
|
68
65
|
sentryService.sendError(Error());
|
|
69
66
|
expect(strapi.log.warn).toHaveBeenCalledWith(expect.stringMatching(/cannot send event/i));
|
|
70
67
|
});
|
|
71
68
|
|
|
72
69
|
it('initializes and sends errors', () => {
|
|
73
|
-
global.strapi.
|
|
74
|
-
|
|
75
|
-
};
|
|
70
|
+
global.strapi.config.get = () => ({ dsn: VALID_DSN, sendMetadata: true });
|
|
71
|
+
const sentryService = sentryServiceLoader({ strapi });
|
|
76
72
|
sentryService.init();
|
|
77
73
|
|
|
78
74
|
// Saves the instance correctly
|
|
@@ -92,10 +88,8 @@ describe('Sentry service', () => {
|
|
|
92
88
|
|
|
93
89
|
it('does not not send metadata when the option is disabled', () => {
|
|
94
90
|
// Init with metadata option disabled
|
|
95
|
-
global.strapi.
|
|
96
|
-
|
|
97
|
-
sendMetadata: false,
|
|
98
|
-
};
|
|
91
|
+
global.strapi.config.get = () => ({ dsn: VALID_DSN, sendMetadata: false });
|
|
92
|
+
const sentryService = sentryServiceLoader({ strapi });
|
|
99
93
|
sentryService.init();
|
|
100
94
|
|
|
101
95
|
// Send error
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
// FIXME
|
|
3
3
|
/* eslint-disable import/extensions */
|
|
4
4
|
const Sentry = require('@sentry/node');
|
|
5
|
-
const defaultSettings = require('../config/settings.json');
|
|
6
5
|
|
|
7
|
-
const createSentryService =
|
|
6
|
+
const createSentryService = strapi => {
|
|
8
7
|
let isReady = false;
|
|
9
8
|
let instance = null;
|
|
10
9
|
let settings = {};
|
|
@@ -15,22 +14,19 @@ const createSentryService = () => {
|
|
|
15
14
|
*/
|
|
16
15
|
init() {
|
|
17
16
|
// Make sure there isn't a Sentry instance already running
|
|
18
|
-
if (instance
|
|
17
|
+
if (instance !== null) {
|
|
19
18
|
return this;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
// Retrieve user settings and merge them with the default ones
|
|
23
|
-
settings =
|
|
24
|
-
...defaultSettings,
|
|
25
|
-
...strapi.plugins.sentry.config,
|
|
26
|
-
};
|
|
22
|
+
settings = strapi.config.get('plugin.sentry');
|
|
27
23
|
|
|
28
24
|
try {
|
|
29
25
|
// Don't init Sentry if no DSN was provided
|
|
30
26
|
if (settings.dsn) {
|
|
31
27
|
Sentry.init({
|
|
32
28
|
dsn: settings.dsn,
|
|
33
|
-
environment: strapi.config.environment,
|
|
29
|
+
environment: strapi.config.get('environment'),
|
|
34
30
|
...settings.init,
|
|
35
31
|
});
|
|
36
32
|
// Store the successfully initialized Sentry instance
|
|
@@ -85,4 +81,4 @@ const createSentryService = () => {
|
|
|
85
81
|
};
|
|
86
82
|
};
|
|
87
83
|
|
|
88
|
-
module.exports = createSentryService();
|
|
84
|
+
module.exports = ({ strapi }) => createSentryService(strapi);
|
package/strapi-admin.js
ADDED
package/strapi-server.js
ADDED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg class="css-15xgryy e10nushx5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 66" width="400" height="367"><path d="M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z" fill="#362d59" transform="translate(11, 11)"></path></svg>
|
package/config/routes.json
DELETED
package/config/settings.json
DELETED
package/controllers/sentry.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = strapi => ({
|
|
4
|
-
beforeInitialize() {
|
|
5
|
-
strapi.config.middleware.load.after.unshift('sentry');
|
|
6
|
-
},
|
|
7
|
-
initialize() {
|
|
8
|
-
const { sentry } = strapi.plugins.sentry.services;
|
|
9
|
-
sentry.init();
|
|
10
|
-
|
|
11
|
-
strapi.app.use(async (ctx, next) => {
|
|
12
|
-
try {
|
|
13
|
-
await next();
|
|
14
|
-
} catch (error) {
|
|
15
|
-
sentry.sendError(error, (scope, sentryInstance) => {
|
|
16
|
-
scope.addEventProcessor(event => {
|
|
17
|
-
// Parse Koa context to add error metadata
|
|
18
|
-
return sentryInstance.Handlers.parseRequest(event, ctx.request, {
|
|
19
|
-
// Don't parse the transaction name, we'll do it manually
|
|
20
|
-
transaction: false,
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
// Manually add transaction name
|
|
24
|
-
scope.setTag('transaction', `${ctx.method} ${ctx.request.url}`);
|
|
25
|
-
// Manually add Strapi version
|
|
26
|
-
scope.setTag('strapi_version', strapi.config.info.strapi);
|
|
27
|
-
scope.setTag('method', ctx.method);
|
|
28
|
-
});
|
|
29
|
-
throw error;
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
},
|
|
33
|
-
});
|