Detecting Browser/Tab crashes
This POC shows how browser crashes could potentially be detected.
How to run demo?
- Run
npm run dev
- Run
npm run server
- Open http://localhost:1234
You can open multiple tabs (each tab will get a unique name)
- Logs are sent to the terminal via server.js
- Try various actions that can simulate a crash
- Once a crash is detected it will be sent to the server and stored in local memory
- http://localhost:1234 will show crashes that were reported
Resources
- https://github.com/getsentry/sentry-javascript/issues/5280
- http://jasonjl.me/blog/2015/06/21/taking-action-on-browser-crashes/
- https://medium.com/@JackPu/how-to-check-browser-crash-via-javascript-fa7d5af5e80b
How does it work?
There are two basic concept:
- Tab tracking
Each browser tab reports its current state on regular intervals. The current state is saved in IndexedDB as a state report.
The state contains properties like: last time when it was active, url, memory usage, etc.
The state is removed from the db when then tab is closed by the user
- Crash detection
A separate process reads all state reports. If it happens that there's a state report that was saved and not removed for long period of time it means the tab was not closed correctly and it probably crashed.
How to use it in my project?
You need to create 2 files for workers and run init function in your app:
detector.worker.js
import { initDetectorWorker } from 'crashme';
initDetectorWorker({
dbName: 'crashme.crashes',
staleThreshold: 60000,
crashThreshold: 5000,
interval: 5000,
});
client.worker.js
import { initDetectorWorker } from 'crashme';
initClientWorker({
dbName: 'crashme.crashes',
pingInterval: 1000,
});
and run function to initialize detection:
import { initCrashDetection } from 'crashme';
export function startReportingCrashes() {
initCrashDetection({
id: Math.random().toString(36).substr(2,5),
dbName: 'crashme.crashes',
createClientWorker: () => {
return new Worker(new URL('./client.worker', import.meta.url));
},
createDetectorWorker: () => {
return new SharedWorker(new URL('./detector.worker', import.meta.url));
},
reportCrash: async (tab) => {
return true;
},
updateInfo: (report) => {
},
});
}