diff --git a/electron/main.js b/electron/main.js index 7dbd764..223fcf3 100644 --- a/electron/main.js +++ b/electron/main.js @@ -108,6 +108,7 @@ app.whenReady().then(async () => { const requiredArguments = [ '--headless', // reticulum meshchat usually launches default web browser, we don't want this when using electron '--port', '9337', // FIXME: let system pick a random unused port? + // '--test-exception-message', 'Test Exception Message', // uncomment to test the crash dialog ]; // if user didn't provide storage dir, we should provide it @@ -122,15 +123,35 @@ app.whenReady().then(async () => { ]); // log stdout + var stdoutLines = []; exeChildProcess.stdout.setEncoding('utf8'); exeChildProcess.stdout.on('data', function(data) { + + // log log(data.toString()); + + // keep track of last 500 stdout lines + stdoutLines.push(data.toString()); + if(stdoutLines.length > 500){ + stdoutLines.shift(); + } + }); // log stderr + var stderrLines = []; exeChildProcess.stderr.setEncoding('utf8'); exeChildProcess.stderr.on('data', function(data) { + + // log log(data.toString()); + + // keep track of last 500 stderr lines + stderrLines.push(data.toString()); + if(stderrLines.length > 500){ + stderrLines.shift(); + } + }); // log errors @@ -139,8 +160,29 @@ app.whenReady().then(async () => { }); // quit electron app if exe dies - exeChildProcess.on('exit', function(code) { + exeChildProcess.on('exit', async function(code) { + + // show crash log + const stdout = stdoutLines.join(""); + const stderr = stderrLines.join(""); + await dialog.showMessageBox(mainWindow, { + message: [ + "MeshChat Crashed!", + "", + `Exit Code: ${code}`, + "", + `----- stdout -----`, + "", + stdout, + `----- stderr -----`, + "", + stderr, + ].join("\n"), + }); + + // quit after dismissing error dialog quit(); + }); } catch(e) { diff --git a/meshchat.py b/meshchat.py index 947d6d6..bcd17a8 100644 --- a/meshchat.py +++ b/meshchat.py @@ -2089,8 +2089,13 @@ def main(): parser.add_argument("--generate-identity-base64", action='store_true', help="Outputs a randomly generated Reticulum Identity as base64 and then exits.") parser.add_argument("--reticulum-config-dir", type=str, help="Path to a Reticulum config directory for the RNS stack to use (e.g: ~/.reticulum)") parser.add_argument("--storage-dir", type=str, help="Path to a directory for storing databases and config files (default: ./storage)") + parser.add_argument("--test-exception-message", type=str, help="Throws an exception. Used for testing the electron error dialog") args = parser.parse_args() + # check if we want to test exception messages + if args.test_exception_message is not None: + raise Exception(args.test_exception_message) + # util to generate reticulum identity and save to file without using rnid if args.generate_identity_file is not None: