Browse Source

rename function and added logging for errors

Rushikesh Tote 3 năm trước cách đây
mục cha
commit
343aa4a75a

+ 5 - 8
src/main/preload.ts

@@ -8,6 +8,7 @@ import {
     updatePendingUploadsFilePaths,
     getElectronFilesFromGoogleZip,
 } from './utils/upload';
+import { logError } from './utils/logging';
 
 const { ipcRenderer } = electron;
 
@@ -56,8 +57,7 @@ const selectRootDirectory = async () => {
     try {
         return await ipcRenderer.invoke('select-dir');
     } catch (e) {
-        console.error(e);
-        throw e;
+        logError(e, 'error while selecting root directory');
     }
 };
 
@@ -115,8 +115,7 @@ const showUploadFilesDialog = async () => {
         const files = await Promise.all(filePaths.map(getElectronFile));
         return files;
     } catch (e) {
-        console.error(e);
-        throw e;
+        logError(e, 'error while selecting files');
     }
 };
 
@@ -128,8 +127,7 @@ const showUploadDirsDialog = async () => {
         const files = await Promise.all(filePaths.map(getElectronFile));
         return files;
     } catch (e) {
-        console.error(e);
-        throw e;
+        logError(e, 'error while selecting folders');
     }
 };
 
@@ -144,8 +142,7 @@ const showUploadZipDialog = async () => {
         const files = filesList.flat();
         return files;
     } catch (e) {
-        console.error(e);
-        throw e;
+        logError(e, 'error while selecting zips');
     }
 };
 

+ 18 - 2
src/main/services/store.ts

@@ -1,7 +1,7 @@
 import Store, { Schema } from 'electron-store';
-import { StoreType } from '../types';
+import { KeysStoreType, UploadStoreType } from '../types';
 
-export const uploadStoreSchema: Schema<StoreType> = {
+export const uploadStoreSchema: Schema<UploadStoreType> = {
     filePaths: {
         type: 'array',
         items: {
@@ -17,3 +17,19 @@ export const uploadStatusStore = new Store({
     name: 'upload-status',
     schema: uploadStoreSchema,
 });
+
+export const keysStoreSchema: Schema<KeysStoreType> = {
+    AnonymizeUserID: {
+        type: 'object',
+        properties: {
+            id: {
+                type: 'string',
+            },
+        },
+    },
+};
+
+export const keysStore = new Store({
+    name: 'keys',
+    schema: keysStoreSchema,
+});

+ 7 - 1
src/main/types/index.ts

@@ -8,7 +8,13 @@ export interface ElectronFile {
     arrayBuffer: () => Promise<Uint8Array>;
 }
 
-export interface StoreType {
+export interface UploadStoreType {
     filePaths: string[];
     collectionName: string;
 }
+
+export interface KeysStoreType {
+    AnonymizeUserID: {
+        id: string;
+    };
+}

+ 5 - 0
src/main/utils/ipcComms.ts

@@ -1,6 +1,7 @@
 import { BrowserWindow, dialog, ipcMain, Tray, Notification } from 'electron';
 import { createWindow } from './createWindow';
 import { buildContextMenu } from './menuUtil';
+import { logErrorSentry } from './sentry';
 import { getFilesFromDir } from './upload';
 
 export default function setupIpcComs(
@@ -62,4 +63,8 @@ export default function setupIpcComs(
 
         return files;
     });
+
+    ipcMain.handle('log-error', (event, err, msg, info?) => {
+        logErrorSentry(err, msg, info);
+    });
 }

+ 5 - 0
src/main/utils/logging.ts

@@ -0,0 +1,5 @@
+import { ipcRenderer } from 'electron';
+
+export function logError(error: Error, message: string, info?: string): void {
+    ipcRenderer.invoke('log-error', error, message, info);
+}

+ 53 - 0
src/main/utils/sentry.ts

@@ -1,6 +1,7 @@
 import * as Sentry from '@sentry/electron/dist/main';
 
 import * as isDev from 'electron-is-dev';
+import { keysStore } from '../services/store';
 
 const SENTRY_DSN = 'https://e9268b784d1042a7a116f53c58ad2165@sentry.ente.io/5';
 
@@ -15,4 +16,56 @@ function initSentry(): void {
     });
 }
 
+export function logErrorSentry(
+    error: any,
+    msg: string,
+    info?: Record<string, unknown>
+) {
+    const err = errorWithContext(error, msg);
+    if (!process.env.NEXT_PUBLIC_SENTRY_ENV) {
+        console.log(error, { msg, info });
+    }
+    Sentry.captureException(err, {
+        level: Sentry.Severity.Info,
+        user: { id: getUserAnonymizedID() },
+        contexts: {
+            ...(info && {
+                info: info,
+            }),
+            rootCause: { message: error?.message },
+        },
+    });
+}
+
+function errorWithContext(originalError: Error, context: string) {
+    const errorWithContext = new Error(context);
+    errorWithContext.stack =
+        errorWithContext.stack.split('\n').slice(2, 4).join('\n') +
+        '\n' +
+        originalError.stack;
+    return errorWithContext;
+}
+
+function makeID(length: number) {
+    let result = '';
+    const characters =
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+    const charactersLength = characters.length;
+    for (let i = 0; i < length; i++) {
+        result += characters.charAt(
+            Math.floor(Math.random() * charactersLength)
+        );
+    }
+    return result;
+}
+
+function getUserAnonymizedID() {
+    let anonymizeUserID = keysStore.get('AnonymizeUserID')?.id;
+    if (!anonymizeUserID) {
+        anonymizeUserID = makeID(6);
+        keysStore.set('AnonymizeUserID', { id: anonymizeUserID });
+    }
+    return anonymizeUserID;
+}
+
 export default initSentry;

+ 2 - 9
src/main/utils/upload.ts

@@ -115,7 +115,7 @@ const getZipFileStream = async (
     return readableStream;
 };
 
-async function getElectronFileWithZip(
+async function getZipEntryasElectronFile(
     zip: StreamZip.StreamZipAsync,
     entry: StreamZip.ZipEntry
 ): Promise<ElectronFile> {
@@ -194,13 +194,6 @@ export const updatePendingUploadsFilePaths = (filePaths: string[]) => {
     uploadStatusStore.set('filePaths', filePaths);
 };
 
-const getValidFilePaths = async (filePaths: string[]) => {
-    return filePaths?.filter(
-        async (filePath) =>
-            await fs.stat(filePath).then((stat) => stat.isFile())
-    );
-};
-
 export const getElectronFilesFromGoogleZip = async (filePath: string) => {
     const zip = new StreamZip.async({
         file: filePath,
@@ -211,7 +204,7 @@ export const getElectronFilesFromGoogleZip = async (filePath: string) => {
 
     for (const entry of Object.values(entries)) {
         if (entry.name.startsWith(GOOGLE_PHOTOS_DIR)) {
-            files.push(await getElectronFileWithZip(zip, entry));
+            files.push(await getZipEntryasElectronFile(zip, entry));
         }
     }