I'm trying to have my electron app do a bunch of cleanup when the app is quit (terminate a few processes, delete some temp files, etc). I am triggering the cleanUp function with the before-quit event. If my computer is running fast, these cleanup operations complete before the app is quit, but if the computer is running slow, the cleanUp function sometimes only executes partially.
Is there a way that I can prevent the app from fully quitting before my cleanUp function has been fully executed?
app.on('before-quit', async () => {
try {
await cleanUp();
} catch (err) {
console.error(err);
}
});
As you can read in the before-quit docs, you can use event.preventDefault() inside the before-quit event handler to prevent the app from terminating.
Your cleanup code can then run unimpeded. At the end of the cleanup, close the app programmatically.
To make sure that before-quit will not block app termination at that time, you probably want to keep track of the current state of the app. You may want to allow the app to terminate inside before-quit if the cleanup code has completed. That means: execute event.preventDefault() only if the cleanup has not been completed yet.
It's probably wise to inform the user about the state of the app: display "shutting down" or something similar, so that it is clear that the app is no longer functional.
Related
If i navigate from the web app, and no longer have any windows open, when i return back to the app the install event is called every time before activate. This doesn't match the expected lifecycle of install only been called once. I'm not making any changes to the service worker file.
The only code in the service worker is:
self.addEventListener('install', function(event) {
console.log('[ServiceWorker:install] Installing service worker v6.');
});
self.addEventListener('activate', event => {
console.log(`[ServiceWorker:activation] Activating service worker v6.`);
});
That is probably old logs.
You can either clear console or add timestamp to the logs to see that ...installing/...activating messages are logged before you closed/opened the browser window.
Credits to this answer: https://stackoverflow.com/a/41153031/4956536
I'm building an electron app that must reload the render process window if a crash happens.
Currently I can restart the app from the main process
app.relaunch();
app.quit();
But I cannot detect the window crashing.
I tried using the
win.on('unresponsive', () => { ... } );
But the event is not getting generated when I crash the process.
To crash the process I tried:
invoking the process.crash()
using all the available memory.
Both ways successfully crash the process but again, I cannot find a way to detect it.
I tried also using, from the render process, the window.onerror(...) and sending via IPC to the main process a message when the crash is detected, but this seems not to work as well.
You should be looking for the 'crashed' event in webContents. Check https://electronjs.org/docs/api/web-contents#event-crashed
For example put something like this in main process:
win.webContents.on('crashed', (e) => {
app.relaunch();
app.quit()
});
maybe look into "pm2-windows-service" which can install your app as windows service and watch if it crashes, to restart it
https://www.npmjs.com/package/pm2-windows-service
also electron has app.setLoginItemSettings({ openAtLogin: true }); but that does not guard for crash, only provide automatic app start at windows login
The app I'm building, when I compile it for distribution packing it with electron-builder, every now and then, dies, showing a blank screen and a disconnected devtools:
Any ideas what's going on or how to start figuring out what's happening here?
Listen for the uncaughtException event and log any error that you get. This will give you insight into what is happening. Then perform any cleanup if necessary and relaunch the app if desired. This allows your app to "recover" from crashes if it is intended to be long-running.
//handle crashes and kill events
process.on('uncaughtException', function(err) {
//log the message and stack trace
fs.writeFileSync('crash.log', err + "\n" + err.stack);
//do any cleanup like shutting down servers, etc
//relaunch the app (if you want)
app.relaunch({args: []});
app.exit(0);
});
You can also listen to the SIGTERM event to see if your application is being killed off, and also gracefully shutdown servers, restart, etc.
process.on('SIGTERM', function() {
fs.writeFileSync('shutdown.log', "Received SIGTERM signal");
//do any cleanup like shutting down servers, etc
//relaunch the app (if you want)
app.relaunch({args: []});
app.exit(0);
});
This can be caused by several different serious faults in the renderer process (out of memory, for example). To fix it, you really have to get your hands on the error.
See https://www.electronjs.org/docs/tutorial/application-debugging#v8-crashes for more details. Specifically, I would recommend settings the ELECTRON_ENABLE_LOGGING environment variable to true before launching the electron process, this should result in the error showing up in the console from which you launch the main process (NOT the chrome devtools console).
I recently discovered Cordova, and started building an app that i've been thinking of. I need to figure out if i, through Cordova, can detect if the user is leaving the app (not locking the phone), or e.g. picking up a phone call, is there an event for this that i can bind to? I've searched through the most npm-library packages and did a lot of research but can't really find a good answer.
Cordova providing Pause and resume events.
pause
The pause event fires when the native platform puts the application into the background, typically when the user switches to a different application.
I think this will help you.
eg:
document.addEventListener("pause", onPause, false);
function onPause() {
// Handle the pause event
}
resume
The resume event fires when the native platform pulls the application out from the background.
iOS Quirks
Any interactive functions called from a pause event handler execute later when the app resumes, as signaled by the resume event. These include alerts, console.log(), and any calls from plugins or the Cordova API, which go through Objective-C.
active event
The iOS-specific active event is available as an alternative to resume, and detects when users disable the Lock button to unlock the device with the app running in the foreground. If the app (and device) is enabled for multi-tasking, this is paired with a subsequent resume event, but only under iOS 5. In effect, all locked apps in iOS 5 that have multi-tasking enabled are pushed to the background. For apps to remain running when locked under iOS 5, disable the app's multi-tasking by setting UIApplicationExitsOnSuspend to YES. To run when locked on iOS 4, this setting does not matter.
resume event
When called from a resume event handler, interactive functions such as alert() need to be wrapped in a setTimeout() call with a timeout value of zero, or else the app hangs. For example:
document.addEventListener("resume", onResume, false);
function onResume() {
setTimeout(function() {
// TODO: do your thing!
}, 0);
}
This is my code
//This is an event that fires when a PhoneGap application is put into the background.
document.addEventListener("pause", onPause, false);
//This is an event that fires when a PhoneGap application is retrieved from the background.
document.addEventListener("resume", onResume, false);
// Handle the pause event
function onPause(){
console.log("pause : app is put into background");
}
// Handle the resume event
function onResume() {
console.log("resume : app is put into foreground");
}
When i press the home button there is no log in the console however when I click the app (make it in foreground) then my log is
2011-11-22 12:11:37.206 Event[644:207] [INFO] pause : app is put into background
2011-11-22 12:11:37.206 Event[644:207] [INFO] resume : app is put into foreground
I don't know why pause function is called when it comes in foreground.
Is there anything that I'm doing wrong?
This is from the docs
iOS Quirks
In the pause handler, any calls that go through Objective-C will not work, nor will any calls that are interactive, like alerts. This means that you cannot call console.log (and its variants), or any calls from Plugins or the PhoneGap API. These will only be processed when the app resumes (processed on the next run-loop).
I suspect what is actually happening is that the console.log() from the pause event is not so much being fired on resume, as it's just that the system cannot output your console.log() until it comes back.
The Objective-C method in PhoneGapDelegate.m that fires the pause event (applicationWillEnterForeground:(UIApplication *)application) sends it to the JavaScript but by then the app is in the background and suspended. The JavaScript cannot receive the event until it re-enters the foreground.
To test this, simply background your app for a longer period of time... it should then cause their error:
void SendDelegateMessage(NSInvocation*): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
This appears to be a bug in PhoneGap. Perhaps you could raise an issue at: https://github.com/callback/callback-ios ?