Desktop: Write a crash dump to disk when the app crashes

pull/9780/head
Laurent Cozic 2024-01-25 11:33:04 +00:00
parent 681d413b36
commit fe3ad3e9b4
3 changed files with 28 additions and 9 deletions

View File

@ -75,6 +75,8 @@ export default class ElectronAppWrapper {
// Assumes that the renderer process may be in an invalid state and so cannot
// be accessed.
public async handleAppFailure(errorMessage: string, canIgnore: boolean, isTesting?: boolean) {
await bridge().captureException(new Error(errorMessage));
const buttons = [];
buttons.push(_('Quit'));
const exitIndex = 0;

View File

@ -130,7 +130,7 @@ class Application extends BaseApplication {
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'autoUploadCrashDumps') {
bridge().autoUploadCrashDumps = action.value;
bridge().setAutoUploadCrashDumps(action.value);
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'style.editor.fontFamily' || action.type === 'SETTING_UPDATE_ALL') {
@ -410,9 +410,7 @@ class Application extends BaseApplication {
argv = await super.start(argv);
bridge().autoUploadCrashDumps = Setting.value('autoUploadCrashDumps');
// this.crashDetectionHandler();
bridge().setAutoUploadCrashDumps(Setting.value('autoUploadCrashDumps'));
await this.applySettingsSideEffects();

View File

@ -2,8 +2,11 @@ import ElectronAppWrapper from './ElectronAppWrapper';
import shim from '@joplin/lib/shim';
import { _, setLocale } from '@joplin/lib/locale';
import { BrowserWindow, nativeTheme, nativeImage } from 'electron';
const { dirname, toSystemSlashes } = require('@joplin/lib/path-utils');
import * as Sentry from '@sentry/electron/main';
import { writeFileSync } from 'fs';
import { homedir } from 'os';
import { msleep } from '@joplin/utils/time';
const { dirname, toSystemSlashes } = require('@joplin/lib/path-utils');
interface LastSelectedPath {
file: string;
@ -32,7 +35,20 @@ export class Bridge {
Sentry.init({
dsn: 'https://cceec550871b1e8a10fee4c7a28d5cf2@o4506576757522432.ingest.sentry.io/4506594281783296',
beforeSend: event => this.autoUploadCrashDumps_ ? event : null,
beforeSend: event => {
try {
const date = (new Date()).toISOString().replace(/[:-]/g, '').split('.')[0];
writeFileSync(`${homedir()}/joplin_crash_dump_${date}.json`, JSON.stringify(event, null, '\t'), 'utf-8');
} catch (error) {
// Ignore the error since we can't handle it here
}
if (!this.autoUploadCrashDumps_) {
return null;
} else {
return event;
}
},
});
}
@ -44,11 +60,14 @@ export class Bridge {
return !this.electronApp().electronApp().isPackaged;
}
public get autoUploadCrashDumps() {
return this.autoUploadCrashDumps_;
public async captureException(error: any) {
Sentry.captureException(error);
// We wait to give the "beforeSend" event handler time to process the crash dump and write
// it to file.
await msleep(10);
}
public set autoUploadCrashDumps(v: boolean) {
public setAutoUploadCrashDumps(v: boolean) {
this.autoUploadCrashDumps_ = v;
}