Skip to content

Commit

Permalink
feat: Send same Sentry event at most once per 24h (#2312)
Browse files Browse the repository at this point in the history
Desktop was not filtering events sent to our Sentry server which could
result in a lot of events being sent at once when facing an issue
which is not resolved quickly during an operation which is retried or
done repeatedly (e.g. errors raised while trying to access PouchDB
while the db is corrupted).

We will now keep track of all events sent in the past 24 hours (or
since the app was last started, whichever is the most recent) and will
only send events that were not sent already in this timespan.
  • Loading branch information
taratatach authored Jul 24, 2023
1 parent 5d800b1 commit eb1d431
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
27 changes: 27 additions & 0 deletions core/utils/sentry.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const url = require('url')
const _ = require('lodash')

const { SESSION_PARTITION_NAME } = require('../../gui/js/network')
const { HOURS } = require('./time')
const logger = require('./logger')

const log = logger({
Expand Down Expand Up @@ -64,6 +65,8 @@ let isSentryConfigured = false
import type { ClientInfo } from '../app'
*/

let ErrorsAlreadySent /* Map<string,Date> */

function setup(clientInfos /*: ClientInfo */) {
if (CI || COZY_NO_SENTRY || isSentryConfigured) {
log.info(
Expand Down Expand Up @@ -105,6 +108,20 @@ function setup(clientInfos /*: ClientInfo */) {
new ExtraErrorDataIntegration({ depth: 10 }),
...defaultIntegrations
]
},
beforeSend: (event, hint) => {
const error = hint.originalException
const message = error && error.message ? error.message : event.message

const alreadySentThisDay =
Number(ErrorsAlreadySent.get(message)) > Date.now() - 24 * HOURS

// Update the last send date for this message
ErrorsAlreadySent.set(message, Date.now())

// Drop events if a similar message has already been sent if the past
// 24 hours (i.e. avoid spamming our Sentry server).
return alreadySentThisDay ? null : event
}
})
Sentry.configureScope(scope => {
Expand All @@ -126,8 +143,18 @@ function setup(clientInfos /*: ClientInfo */) {
}
}
})
ErrorsAlreadySent = new Map()
isSentryConfigured = true
log.info('Sentry configured !')

// Cleanup errors journal to prevent an ever growing Map
setInterval(() => {
for (const [msg, sentAt] of ErrorsAlreadySent.entries()) {
if (sentAt < Date.now() - 24 * HOURS) {
ErrorsAlreadySent.delete(msg)
}
}
}, 1 * HOURS)
} catch (err) {
// eslint-disable-next-line no-console
console.log('FAIL TO SETUP', err)
Expand Down
4 changes: 3 additions & 1 deletion core/utils/time.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
const MILLISECONDS = 1
const SECONDS = 1000 * MILLISECONDS
const MINUTES = 60 * SECONDS
const HOURS = 60 * MINUTES

module.exports = {
MILLISECONDS,
SECONDS,
MINUTES
MINUTES,
HOURS
}

0 comments on commit eb1d431

Please sign in to comment.