diff --git a/src/apps/main/background-processes/sync-engine.ts b/src/apps/main/background-processes/sync-engine.ts
index 3f97d7ecc..cce03edc1 100644
--- a/src/apps/main/background-processes/sync-engine.ts
+++ b/src/apps/main/background-processes/sync-engine.ts
@@ -43,7 +43,9 @@ function scheduleHeathCheck() {
// Logger.debug('Health check succeeded');
})
.catch(() => {
- Logger.warn('Health check failed, relaunching the worker');
+ const warning = 'Health check failed, relaunching the worker';
+ Logger.warn(warning);
+ Sentry.captureMessage(warning);
workerIsRunning = false;
worker?.destroy();
spawnSyncEngineWorker();
diff --git a/src/apps/main/main.ts b/src/apps/main/main.ts
index 26e16b2f9..2cafa8338 100644
--- a/src/apps/main/main.ts
+++ b/src/apps/main/main.ts
@@ -64,11 +64,13 @@ Logger.log(`Running ${packageJson.version}`);
Logger.log('Initializing Sentry for main process');
if (process.env.SENTRY_DSN) {
+ Logger.log(`App is packaged: ${app.isPackaged}`);
Sentry.init({
// Enable Sentry only when app is packaged
enabled: app.isPackaged,
dsn: process.env.SENTRY_DSN,
});
+ Sentry.captureMessage('Main process started');
Logger.log('Sentry is ready for main process');
} else {
Logger.error('Sentry DSN not found, cannot initialize Sentry');
diff --git a/src/apps/main/realtime.ts b/src/apps/main/realtime.ts
index d390c4058..756b2a231 100644
--- a/src/apps/main/realtime.ts
+++ b/src/apps/main/realtime.ts
@@ -3,7 +3,7 @@ import { io, Socket } from 'socket.io-client';
import { obtainToken } from './auth/service';
import eventBus from './event-bus';
import { broadcastToWindows } from './windows';
-import { reportError } from '../renderer/utils/errors';
+import * as Sentry from '@sentry/electron/main';
type XHRRequest = {
getResponseHeader: (headerName: string) => string[] | null;
@@ -54,11 +54,12 @@ function cleanAndStartRemoteNotifications() {
socket.on('disconnect', (reason) => {
logger.log('❌ Remote notifications disconnected, reason: ', reason);
+ Sentry.captureException(reason);
});
socket.on('connect_error', (error) => {
logger.error('❌ Remote notifications connect error: ', error);
- reportError(error);
+ Sentry.captureException(error);
});
socket.on('event', (data) => {
diff --git a/src/apps/renderer/hooks/VirtualDriveStatus.tsx b/src/apps/renderer/hooks/VirtualDriveStatus.tsx
index 6acd47a5d..2c7813740 100644
--- a/src/apps/renderer/hooks/VirtualDriveStatus.tsx
+++ b/src/apps/renderer/hooks/VirtualDriveStatus.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
-import { reportError } from '../utils/errors';
+import { reportError } from '../utils/sentry';
import { VirtualDriveStatus } from '../../shared/types/VirtualDriveStatus';
export default function useVirtualDriveStatus() {
diff --git a/src/apps/renderer/index.tsx b/src/apps/renderer/index.tsx
index 7029174ef..260afa255 100644
--- a/src/apps/renderer/index.tsx
+++ b/src/apps/renderer/index.tsx
@@ -1,4 +1,6 @@
import { render } from 'react-dom';
import App from './App';
+import { initSentry } from './utils/sentry';
+initSentry();
render(, document.getElementById('root'));
diff --git a/src/apps/renderer/pages/Feedback/index.tsx b/src/apps/renderer/pages/Feedback/index.tsx
index 45070821f..5963d4eea 100644
--- a/src/apps/renderer/pages/Feedback/index.tsx
+++ b/src/apps/renderer/pages/Feedback/index.tsx
@@ -4,7 +4,7 @@ import { useTranslationContext } from '../../context/LocalContext';
import { ChatsCircle } from 'phosphor-react';
import WindowTopBar from '../../components/WindowTopBar';
import TextArea from '../../components/TextArea';
-import { reportError } from '../../utils/errors';
+import { reportError } from '../../utils/sentry';
const CHARACTERS_LIMIT = 1000;
export default function Feedback() {
diff --git a/src/apps/renderer/pages/Login/index.tsx b/src/apps/renderer/pages/Login/index.tsx
index f2eef050e..88cc5d2e4 100644
--- a/src/apps/renderer/pages/Login/index.tsx
+++ b/src/apps/renderer/pages/Login/index.tsx
@@ -10,6 +10,7 @@ import Button from '../../components/Button';
import PasswordInput from '../../components/PasswordInput';
import TextInput from '../../components/TextInput';
import WindowTopBar from '../../components/WindowTopBar';
+import { reportError, setUserContextForReports } from '../../utils/sentry';
const TOWFA_ERROR_MESSAGE = 'Wrong 2-factor auth code';
@@ -38,18 +39,20 @@ export default function Login() {
try {
const res = await accessRequest(email, password, encryptedHash, twoFA);
+ setUserContextForReports(res.user);
window.electron.userLoggedIn(res);
} catch (err) {
const { message } = err as Error;
const phaseToSet =
- message === TOWFA_ERROR_MESSAGE ? '2fa' : 'credentials';
+ message === TOWFA_ERROR_MESSAGE ? '2fa' : 'credentials';
setState('error');
setPhase(phaseToSet);
// TODO: adjust styles to acomodate longer error messages
setErrorDetails(translate('login.2fa.wrong-code'));
window.electron.userLogginFailed(email);
+ reportError(err);
}
}
diff --git a/src/apps/renderer/pages/Migration/index.tsx b/src/apps/renderer/pages/Migration/index.tsx
index 5afb9e4e7..7e23027d3 100644
--- a/src/apps/renderer/pages/Migration/index.tsx
+++ b/src/apps/renderer/pages/Migration/index.tsx
@@ -3,7 +3,7 @@ import { SLIDES } from './config';
import { MigrationSlideProps } from './helpers';
import { useTranslationContext } from '../../context/LocalContext';
import useClientPlatform from '../../hooks/ClientPlatform';
-import { reportError } from '../../utils/errors';
+import { reportError } from '../../utils/sentry';
const totalSlides = SLIDES.length - 3;
diff --git a/src/apps/renderer/pages/Widget/Header.tsx b/src/apps/renderer/pages/Widget/Header.tsx
index 33dca6632..f5e398792 100644
--- a/src/apps/renderer/pages/Widget/Header.tsx
+++ b/src/apps/renderer/pages/Widget/Header.tsx
@@ -10,7 +10,7 @@ import useGeneralIssues from '../../hooks/GeneralIssues';
import useProcessIssues from '../../hooks/ProcessIssues';
import useUsage from '../../hooks/useUsage';
import useVirtualDriveStatus from '../../hooks/VirtualDriveStatus';
-import { reportError } from '../../utils/errors';
+import { reportError } from '../../utils/sentry';
export default function Header() {
const { translate } = useTranslationContext();
diff --git a/src/apps/renderer/utils/errors.ts b/src/apps/renderer/utils/errors.ts
deleted file mode 100644
index 852bd31bb..000000000
--- a/src/apps/renderer/utils/errors.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import * as Sentry from '@sentry/electron/renderer';
-
-/**
- * Reports an error to Sentry from the renderer process
- *
- * @param error The error to be reported
- * @param context The context to attach to the error such the userId, tags, boolean values...
- */
-export const reportError = (
- error: unknown,
- context: Record = {}
-) => {
- Sentry.captureException(error, context);
-};
diff --git a/src/apps/renderer/utils/sentry.ts b/src/apps/renderer/utils/sentry.ts
new file mode 100644
index 000000000..348fbe3e9
--- /dev/null
+++ b/src/apps/renderer/utils/sentry.ts
@@ -0,0 +1,44 @@
+import * as Sentry from '@sentry/electron/renderer';
+import { User } from '../../main/types';
+
+/**
+ * Init Sentry in the renderer process
+ * @param dsn Sentry DSN
+ * @param enabled Whether Sentry should be enabled or not
+ */
+export const initSentry = () => {
+ Sentry.init({
+ dsn: process.env.SENTRY_DSN,
+ enabled: true, // it is true but is using app.isPackaged from the main process
+ });
+ Sentry.captureMessage('Render process started');
+};
+
+/**
+ * Reports an error to Sentry from the renderer process
+ *
+ * @param error The error to be reported
+ * @param context The context to attach to the error such the userId, tags, boolean values...
+ */
+export const reportError = (
+ error: unknown,
+ context: Record = {}
+) => {
+ Sentry.captureException(error, context);
+};
+
+
+/**
+ * Set user context in Sentry
+ * @param user User object
+ */
+export const setUserContextForReports = (user: User) => {
+ if (!user) {
+ Sentry.setUser(null);
+ return;
+ }
+ Sentry.setUser({
+ email: user.email,
+ id: user.uuid,
+ });
+};
diff --git a/src/apps/sync-engine/index.ts b/src/apps/sync-engine/index.ts
index b72836c69..903a261f5 100644
--- a/src/apps/sync-engine/index.ts
+++ b/src/apps/sync-engine/index.ts
@@ -6,6 +6,17 @@ import { BindingsManager } from './BindingManager';
import fs from 'fs/promises';
import { iconPath } from '../utils/icon';
import * as Sentry from '@sentry/electron/renderer';
+
+function initSentry() {
+ Sentry.init({
+ dsn: process.env.SENTRY_DSN,
+ enabled: true // it is true but is using app.isPackaged from the main process
+ });
+ Sentry.captureMessage('Sync engine process started');
+}
+
+initSentry();
+
async function ensureTheFolderExist(path: string) {
try {
await fs.access(path);
@@ -16,6 +27,7 @@ async function ensureTheFolderExist(path: string) {
}
async function setUp() {
+
Logger.info('[SYNC ENGINE] Starting sync engine process');
const virtualDrivePath = await ipcRenderer.invoke('get-virtual-drive-root');
@@ -97,8 +109,8 @@ setUp()
Logger.error('[SYNC ENGINE] Error setting up', error);
Sentry.captureException(error);
if (error.toString().includes('Error: ConnectSyncRoot failed')) {
- Sentry.captureMessage('ConnectSyncRoot failed');
Logger.info('[SYNC ENGINE] We neeed to restart the app virtual drive');
+ Sentry.captureMessage('Restarting sync engine virtual drive is required');
}
ipcRenderer.send('SYNC_ENGINE_PROCESS_SETUP_FAILED');
});