0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Improved Sentry logging for AJAX errors in admin (#18829)

no issue

- Currently AJAX errors that surface in Admin get logged to Sentry with
super generic messages like "Error"
- This commit adds more context to the information that's sent to sentry
and should make it easier to identify the error at a glance
This commit is contained in:
Chris Raible 2023-11-01 14:03:32 -07:00 committed by GitHub
parent 9a8c703e34
commit c91527efc8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 4 deletions

View file

@ -181,7 +181,8 @@ export default Route.extend(ShortcutsRoute, {
dsn: this.config.sentry_dsn,
environment: this.config.sentry_env,
release: `ghost@${this.config.version}`,
beforeSend(event) {
beforeSend(event, hint) {
const exception = hint.originalException;
event.tags = event.tags || {};
event.tags.shown_to_user = event.tags.shown_to_user || false;
event.tags.grammarly = !!document.querySelector('[data-gr-ext-installed]');
@ -191,6 +192,14 @@ export default Route.extend(ShortcutsRoute, {
return null;
}
// ajax errors — improve logging and add context for debugging
if (exception && exception.payload && isEmberArray(exception.payload.errors) && exception.payload.errors.length > 0) {
const error = exception.payload.errors[0];
event.exception.values[0].type = `${error.type}: ${error.context}`;
event.exception.values[0].value = error.message;
event.exception.values[0].context = error.context;
}
return event;
},
// TransitionAborted errors surface from normal application behaviour

View file

@ -1,3 +1,4 @@
import * as Sentry from '@sentry/ember';
import AjaxService from 'ember-ajax/services/ajax';
import classic from 'ember-classic-decorator';
import config from 'ghost-admin/config/environment';
@ -5,7 +6,6 @@ import moment from 'moment-timezone';
import semverCoerce from 'semver/functions/coerce';
import semverLt from 'semver/functions/lt';
import {AjaxError, isAjaxError, isForbiddenError} from 'ember-ajax/errors';
import {captureMessage} from '@sentry/ember';
import {get} from '@ember/object';
import {inject} from 'ghost-admin/decorators/inject';
import {isArray as isEmberArray} from '@ember/array';
@ -271,7 +271,7 @@ class ajaxService extends AjaxService {
success = true;
if (attempts !== 0 && this.config.sentry_dsn) {
captureMessage('Request took multiple attempts', {extra: getErrorData()});
Sentry.captureMessage('Request took multiple attempts', {extra: getErrorData()});
}
return result;
@ -289,7 +289,7 @@ class ajaxService extends AjaxService {
await timeout(retryPeriods[attempts] || retryPeriods[retryPeriods.length - 1]);
attempts += 1;
} else if (attempts > 0 && this.config.sentry_dsn) {
captureMessage('Request failed after multiple attempts', {extra: getErrorData()});
Sentry.captureMessage('Request failed after multiple attempts', {extra: getErrorData()});
throw error;
} else {
throw error;
@ -299,6 +299,16 @@ class ajaxService extends AjaxService {
}
handleResponse(status, headers, payload, request) {
// set some context variables for Sentry in case there is an error
Sentry.setContext('ajax', {
url: request.url,
method: request.method,
status
});
Sentry.setTag('ajax.status', status);
Sentry.setTag('ajax.url', request.url);
Sentry.setTag('ajax.method', request.method);
if (headers['content-version']) {
const contentVersion = semverCoerce(headers['content-version']);
const appVersion = semverCoerce(config.APP.version);