From 5b2194d5e8c6f9932fa94049cc6e861791950bb7 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Wed, 26 May 2021 17:01:18 +0100 Subject: [PATCH] Added Sentry error tracking for unhandled exceptions and API errors refs https://github.com/TryGhost/Team/issues/723 - if the `/site/` API returns a `sentry_dsn` then we configure Sentry for error reporting as soon as we've loaded the initial unauthenticated data - once we're authenticated and we have the full Ghost version available, override the Sentry event processor to use the full release - updated `notifications.showAlert()` which is our fallback for API errors that shows the red banner at the top - these are the errors we're most interested in getting visibility for and reducing --- ghost/admin/app/routes/application.js | 29 ++++- ghost/admin/app/services/notifications.js | 6 + ghost/admin/config/environment.js | 5 + ghost/admin/package.json | 1 + ghost/admin/yarn.lock | 134 +++++++++++++++++++++- 5 files changed, 173 insertions(+), 2 deletions(-) diff --git a/ghost/admin/app/routes/application.js b/ghost/admin/app/routes/application.js index 1eae06163b..2e724b8909 100644 --- a/ghost/admin/app/routes/application.js +++ b/ghost/admin/app/routes/application.js @@ -4,6 +4,8 @@ import Route from '@ember/routing/route'; import ShortcutsRoute from 'ghost-admin/mixins/shortcuts-route'; import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd'; import windowProxy from 'ghost-admin/utils/window-proxy'; +import {InitSentryForEmber} from '@sentry/ember'; +import {configureScope} from '@sentry/browser'; import { isAjaxError, isNotFoundError, @@ -49,7 +51,18 @@ export default Route.extend(ShortcutsRoute, { }, beforeModel() { - return this.config.fetchUnauthenticated(); + return this.config.fetchUnauthenticated() + .then(() => { + // init Sentry here rather than app.js so that we can use API-supplied + // sentry_dsn and sentry_env rather than building it into release assets + if (this.config.get('sentry_dsn')) { + InitSentryForEmber({ + dsn: this.config.get('sentry_dsn'), + environment: this.config.get('sentry_env'), + release: `ghost@${this.config.get('version')}` + }); + } + }); }, afterModel(model, transition) { @@ -68,6 +81,20 @@ export default Route.extend(ShortcutsRoute, { ]).then((results) => { this._appLoaded = true; + // update Sentry with the full Ghost version which we only get after authentication + if (this.config.get('sentry_dsn')) { + configureScope((scope) => { + scope.addEventProcessor((event) => { + return new Promise((resolve) => { + resolve({ + ...event, + release: `ghost@${this.config.get('version')}` + }); + }); + }); + }); + } + // kick off background update of "whats new" // - we don't want to block the router for this // - we need the user details to know what the user has seen diff --git a/ghost/admin/app/services/notifications.js b/ghost/admin/app/services/notifications.js index 2ed0290023..e913318226 100644 --- a/ghost/admin/app/services/notifications.js +++ b/ghost/admin/app/services/notifications.js @@ -1,4 +1,5 @@ import Service, {inject as service} from '@ember/service'; +import {captureMessage} from '@sentry/browser'; import {dasherize} from '@ember/string'; import {A as emberA, isArray as isEmberArray} from '@ember/array'; import {filter} from '@ember/object/computed'; @@ -29,6 +30,7 @@ export default Service.extend({ this.content = emberA(); }, + config: service(), upgradeStatus: service(), alerts: filter('content', function (notification) { @@ -99,6 +101,10 @@ export default Service.extend({ }, showAPIError(resp, options) { + if (this.config.get('sentry_dsn')) { + captureMessage(resp); + } + // handle "global" errors if (isVersionMismatchError(resp)) { return this.upgradeStatus.requireUpgrade(); diff --git a/ghost/admin/config/environment.js b/ghost/admin/config/environment.js index 43e312f96a..1ed08e4c46 100644 --- a/ghost/admin/config/environment.js +++ b/ghost/admin/config/environment.js @@ -39,6 +39,11 @@ module.exports = function (environment) { emberKeyboard: { disableInputsInitializer: true + }, + + '@sentry/ember': { + disablePerformance: true, + sentry: {} } }; diff --git a/ghost/admin/package.json b/ghost/admin/package.json index 4f6c7d2c0c..9d8a2260bf 100644 --- a/ghost/admin/package.json +++ b/ghost/admin/package.json @@ -30,6 +30,7 @@ "@ember/render-modifiers": "1.0.2", "@glimmer/component": "1.0.4", "@html-next/vertical-collection": "2.0.0", + "@sentry/ember": "6.4.1", "@tryghost/helpers": "1.1.45", "@tryghost/kg-clean-basic-html": "1.0.17", "@tryghost/kg-parser-plugins": "1.1.7", diff --git a/ghost/admin/yarn.lock b/ghost/admin/yarn.lock index 89d6060613..6725df7bc9 100644 --- a/ghost/admin/yarn.lock +++ b/ghost/admin/yarn.lock @@ -1338,6 +1338,45 @@ walk-sync "^1.1.3" wrap-legacy-hbs-plugin-if-needed "^1.0.1" +"@embroider/core@0.37.0": + version "0.37.0" + resolved "https://registry.yarnpkg.com/@embroider/core/-/core-0.37.0.tgz#bd7a7d63795794ffcd53d90a65b81e939ccf6cff" + integrity sha512-tkXD7qV9GJYb7cGlxLT4PTbPZ+B4vNDXp5oHyEz8EQSuZExN/40Hm90S5KrEC++TpqeVewSIXOz/fA53lkK6RQ== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.12.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-runtime" "^7.12.1" + "@babel/runtime" "^7.12.5" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" + "@embroider/macros" "0.37.0" + assert-never "^1.1.0" + babel-plugin-syntax-dynamic-import "^6.18.0" + broccoli-node-api "^1.7.0" + broccoli-persistent-filter "^3.1.2" + broccoli-plugin "^4.0.1" + broccoli-source "^3.0.0" + debug "^3.1.0" + escape-string-regexp "^4.0.0" + fast-sourcemap-concat "^1.4.0" + filesize "^4.1.2" + fs-extra "^7.0.1" + fs-tree-diff "^2.0.0" + handlebars "^4.4.2" + js-string-escape "^1.0.1" + jsdom "^16.4.0" + json-stable-stringify "^1.0.1" + lodash "^4.17.10" + pkg-up "^3.1.0" + resolve "^1.8.1" + resolve-package-path "^1.2.2" + semver "^7.3.2" + strip-bom "^3.0.0" + typescript-memoize "^1.0.0-alpha.3" + walk-sync "^1.1.3" + wrap-legacy-hbs-plugin-if-needed "^1.0.1" + "@embroider/macros@0.24.1", "@embroider/macros@^0.24.1": version "0.24.1" resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.24.1.tgz#0ab11b88d148f35c91f438f0b44f96fbf1607a9b" @@ -1398,6 +1437,21 @@ resolve "^1.8.1" semver "^7.3.2" +"@embroider/macros@0.37.0", "@embroider/macros@~0.37.0": + version "0.37.0" + resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.37.0.tgz#221013fc5bc0eaa78f1de98802fc03e588bfe1b1" + integrity sha512-VItxn4NzGR5prryXGbPGTuLMd+QPPKvAYZv2357iS+wmz6mTzC5nqXljwDQIOJbAji9giDO+FW2HzXYOcY3teQ== + dependencies: + "@babel/core" "^7.12.3" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" + "@embroider/core" "0.37.0" + assert-never "^1.1.0" + ember-cli-babel "^7.23.0" + lodash "^4.17.10" + resolve "^1.8.1" + semver "^7.3.2" + "@embroider/macros@^0.40.0": version "0.40.0" resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.40.0.tgz#f58763b4cfb9b4089679b478a28627595341bc5a" @@ -1613,6 +1667,84 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@sentry/browser@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.4.1.tgz#b6c62736caaade7fdf6638513d9aad138abde2ac" + integrity sha512-3cDud6GWutnJqcnheIq0lPNTsUJbrRLevQ+g1YfawVXFUxfmmY2bOsGd/Mxq17LxYeBHgKTitXv3DU1bsQ+WBQ== + dependencies: + "@sentry/core" "6.4.1" + "@sentry/types" "6.4.1" + "@sentry/utils" "6.4.1" + tslib "^1.9.3" + +"@sentry/core@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.4.1.tgz#789b0071996de5c1a20673f879408926aa3b4fa6" + integrity sha512-Lx13oTiP+Tjvm5VxulcCszNVd2S1wY4viSnr+ygq62ySVERR+t7uOZDSARZ0rZ259GwW6nkbMh9dDmD0d6VCGQ== + dependencies: + "@sentry/hub" "6.4.1" + "@sentry/minimal" "6.4.1" + "@sentry/types" "6.4.1" + "@sentry/utils" "6.4.1" + tslib "^1.9.3" + +"@sentry/ember@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/ember/-/ember-6.4.1.tgz#632c739942dd29311b83f0b6d4344dee4c2eddb4" + integrity sha512-e3N5EK+mtZGqIk4wkt1E3Wh5beKuGlydSuNrTSaAJcJ45I8kyZ93mX47yjs4uyrY7eSiDYLQqUBu683YhInwZQ== + dependencies: + "@embroider/macros" "~0.37.0" + "@sentry/browser" "6.4.1" + "@sentry/tracing" "6.4.1" + "@sentry/types" "6.4.1" + "@sentry/utils" "6.4.1" + ember-auto-import "^1.6.0" + ember-cli-babel "^7.20.5" + ember-cli-htmlbars "^5.1.2" + ember-cli-typescript "^3.1.4" + +"@sentry/hub@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.4.1.tgz#fa9c05ca32674e2e8477120b71084a1c91a5e023" + integrity sha512-7IZRP5buDE6s/c3vWzzPR/ySE+8GUuHPgTEPiDCPOCWwUN11zXDafJDKkJqY3muJfebUKmC/JG67RyBx+XlnlQ== + dependencies: + "@sentry/types" "6.4.1" + "@sentry/utils" "6.4.1" + tslib "^1.9.3" + +"@sentry/minimal@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.4.1.tgz#d3f968c060c3d3cc997071756659e24047b5dd97" + integrity sha512-4x/PRbDZACCKJqjta9EkhiIMyGMf7VgBX13EEWEDVWLP7ymFukBuTr4ap/Tz9429kB/yXZuDGGMIZp/G618H3g== + dependencies: + "@sentry/hub" "6.4.1" + "@sentry/types" "6.4.1" + tslib "^1.9.3" + +"@sentry/tracing@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.4.1.tgz#3a9119e1ef5206ea565854c325b19a317cc1cca7" + integrity sha512-EPRadE9n/wpUjx4jqP/8vXdOAZBk7vjlzRKniJgKgQUO3v03i0ui6xydaal2mvhplIyOCI2muXdGhjUO7ga4uw== + dependencies: + "@sentry/hub" "6.4.1" + "@sentry/minimal" "6.4.1" + "@sentry/types" "6.4.1" + "@sentry/utils" "6.4.1" + tslib "^1.9.3" + +"@sentry/types@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.4.1.tgz#7c0a4355a1d04321b901197723a8f55c263226e9" + integrity sha512-sTu/GaLsLYk1AkAqpkMT4+4q665LtZjhV0hkgiTD4N3zPl5uSf1pCIzxPRYjOpe7NEANmWv8U4PaGKGtc2eMfA== + +"@sentry/utils@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.4.1.tgz#55fa7da58898773cbd538e4895fc2e4ec695ecab" + integrity sha512-xJ1uVa5fvg23pXQfulvCIBb9pQ3p1awyd1PapK2AYi+wKjTuYl4B9edmhjRREEQEExznl/d2OVm78fRXLq7M9Q== + dependencies: + "@sentry/types" "6.4.1" + tslib "^1.9.3" + "@simple-dom/interface@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" @@ -14166,7 +14298,7 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -tslib@^1.9.0: +tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==