fix(electron): potential crash on quit (#8855)

This commit is contained in:
Peng Xiao
2024-11-20 14:44:06 +08:00
committed by GitHub
parent b0ca3c6d58
commit 8689465e00
6 changed files with 42 additions and 12 deletions

View File

@@ -97,6 +97,7 @@ jobs:
SENTRY_PROJECT: 'affine' SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ needs.before-make.outputs.RELEASE_VERSION }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }} MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -213,6 +214,7 @@ jobs:
SENTRY_PROJECT: 'affine' SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ needs.before-make.outputs.RELEASE_VERSION }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }} MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@@ -0,0 +1,20 @@
import { app } from 'electron';
import { logger } from './logger';
const cleanupRegistry: (() => void)[] = [];
export function beforeAppQuit(fn: () => void) {
cleanupRegistry.push(fn);
}
app.on('before-quit', () => {
cleanupRegistry.forEach(fn => {
// some cleanup functions might throw on quit and crash the app
try {
fn();
} catch (err) {
logger.warn('cleanup error on quit', err);
}
});
});

View File

@@ -1,7 +1,8 @@
import { app, BrowserWindow, WebContentsView } from 'electron'; import { BrowserWindow, WebContentsView } from 'electron';
import { AFFINE_EVENT_CHANNEL_NAME } from '../shared/type'; import { AFFINE_EVENT_CHANNEL_NAME } from '../shared/type';
import { applicationMenuEvents } from './application-menu'; import { applicationMenuEvents } from './application-menu';
import { beforeAppQuit } from './cleanup';
import { logger } from './logger'; import { logger } from './logger';
import { sharedStorageEvents } from './shared-storage'; import { sharedStorageEvents } from './shared-storage';
import { uiEvents } from './ui/events'; import { uiEvents } from './ui/events';
@@ -56,14 +57,10 @@ export function registerEvents() {
unsubs.push(unsubscribe); unsubs.push(unsubscribe);
} }
} }
app.on('before-quit', () => {
// subscription on quit sometimes crashes the app unsubs.forEach(unsub => {
unsubs.forEach(unsub => { beforeAppQuit(() => {
try { unsub();
unsub();
} catch (err) {
logger.warn('unsubscribe error on quit', err);
}
}); });
}); });
} }

View File

@@ -13,6 +13,7 @@ import {
import type { HelperToMain, MainToHelper } from '../shared/type'; import type { HelperToMain, MainToHelper } from '../shared/type';
import { MessageEventChannel } from '../shared/utils'; import { MessageEventChannel } from '../shared/utils';
import { beforeAppQuit } from './cleanup';
import { logger } from './logger'; import { logger } from './logger';
const HELPER_PROCESS_PATH = path.join(__dirname, './helper.js'); const HELPER_PROCESS_PATH = path.join(__dirname, './helper.js');
@@ -65,7 +66,7 @@ class HelperProcessManager {
}); });
}); });
app.on('before-quit', () => { beforeAppQuit(() => {
this.#process.kill(); this.#process.kill();
}); });
} }

View File

@@ -5,6 +5,7 @@ import electronWindowState from 'electron-window-state';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { isLinux, isMacOS, isWindows } from '../../shared/utils'; import { isLinux, isMacOS, isWindows } from '../../shared/utils';
import { beforeAppQuit } from '../cleanup';
import { buildType } from '../config'; import { buildType } from '../config';
import { mainWindowOrigin } from '../constants'; import { mainWindowOrigin } from '../constants';
import { ensureHelperProcess } from '../helper-process'; import { ensureHelperProcess } from '../helper-process';
@@ -116,11 +117,17 @@ export class MainWindowManager {
uiSubjects.onFullScreen$.next(mainWindow.isFullScreen()); uiSubjects.onFullScreen$.next(mainWindow.isFullScreen());
}); });
beforeAppQuit(() => {
this.cleanupWindows();
});
mainWindow.on('close', e => { mainWindow.on('close', e => {
// TODO(@pengx17): gracefully close the app, for example, ask user to save unsaved changes // TODO(@pengx17): gracefully close the app, for example, ask user to save unsaved changes
e.preventDefault(); e.preventDefault();
if (!isMacOS()) { if (!isMacOS()) {
closeAllWindows(); closeAllWindows();
this.mainWindowReady = undefined;
this.mainWindow$.next(undefined);
} else { } else {
// hide window on macOS // hide window on macOS
// application quit will be handled by closing the hidden window // application quit will be handled by closing the hidden window

View File

@@ -25,6 +25,7 @@ import {
} from 'rxjs'; } from 'rxjs';
import { isMacOS } from '../../shared/utils'; import { isMacOS } from '../../shared/utils';
import { beforeAppQuit } from '../cleanup';
import { CLOUD_BASE_URL, isDev } from '../config'; import { CLOUD_BASE_URL, isDev } from '../config';
import { mainWindowOrigin, shellViewUrl } from '../constants'; import { mainWindowOrigin, shellViewUrl } from '../constants';
import { ensureHelperProcess } from '../helper-process'; import { ensureHelperProcess } from '../helper-process';
@@ -749,8 +750,10 @@ export class WebContentViewsManager {
}) })
); );
app.on('before-quit', () => { disposables.forEach(d => {
disposables.forEach(d => d.unsubscribe()); beforeAppQuit(() => {
d.unsubscribe();
});
}); });
const focusActiveView = () => { const focusActiveView = () => {