mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
fix(electron): potential crash on quit (#8855)
This commit is contained in:
2
.github/workflows/release-desktop.yml
vendored
2
.github/workflows/release-desktop.yml
vendored
@@ -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
|
||||||
|
|||||||
20
packages/frontend/apps/electron/src/main/cleanup.ts
Normal file
20
packages/frontend/apps/electron/src/main/cleanup.ts
Normal 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user