mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-25 01:36:06 +08:00
918090a4e1
Summary:
The goal is to let us see what plugins are throwing errors on Sentry.
We are using a Sentry `tag` to identify and group plugins and their
errors.
Along the way, I cleaned up the error catching and reporting system. There
was a lot of duplicate error logic (that wasn't always right) and some
legacy Atom error handling.
Now, if you catch an error that we should report (like when handling
extensions), call `NylasEnv.reportError`. This used to be called
`emitError` but I changed it to `reportError` to be consistent with the
ErrorReporter and be a bit more indicative of what it does.
In the production version, the `ErrorLogger` will forward the request to
the `nylas-private-error-reporter` which will report to Sentry.
The `reportError` function also now inspects the stack to determine which
plugin(s) it came from. These are passed along to Sentry.
I also cleaned up the `console.log` and `console.error` code. We were
logging errors multiple times making the console confusing to read. Worse
is that we were logging the `error` object, which would print not the
stack of the actual error, but rather the stack of where the console.error
was logged from. Printing `error.stack` instead shows much more accurate
stack traces.
See changes in the Edgehill repo here: 8c4a86eb7e
Test Plan: Manual
Reviewers: juan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2509
101 lines
2.8 KiB
JavaScript
101 lines
2.8 KiB
JavaScript
import path from 'path';
|
|
import NylasStore from 'nylas-store';
|
|
import {remote, ipcRenderer} from 'electron';
|
|
import {UnreadBadgeStore, CanvasUtils} from 'nylas-exports';
|
|
const NativeImage = remote.require('native-image');
|
|
const Menu = remote.require('menu');
|
|
const {canvasWithSystemTrayIconAndText} = CanvasUtils;
|
|
|
|
// Must be absolute real system path
|
|
// https://github.com/atom/electron/issues/1299
|
|
const BASE_ICON_PATH = path.join(__dirname, '..', 'assets', process.platform, 'ic-systemtray-nylas.png');
|
|
const UNREAD_ICON_PATH = path.join(__dirname, '..', 'assets', process.platform, 'ic-systemtray-nylas-unread.png');
|
|
|
|
const _menuTemplate = [
|
|
{
|
|
label: 'New Message',
|
|
click: ()=> ipcRenderer.send('command', 'application:new-message'),
|
|
},
|
|
{
|
|
label: 'Preferences',
|
|
click: ()=> ipcRenderer.send('command', 'application:open-preferences'),
|
|
},
|
|
{
|
|
type: 'separator',
|
|
},
|
|
{
|
|
label: 'Quit N1',
|
|
click: ()=> ipcRenderer.send('command', 'application:quit'),
|
|
},
|
|
];
|
|
|
|
if (process.platform !== 'win32') {
|
|
_menuTemplate.unshift({
|
|
label: 'Open Inbox',
|
|
click: ()=> ipcRenderer.send('command', 'application:show-main-window'),
|
|
});
|
|
}
|
|
|
|
const _buildMenu = ()=> {
|
|
return Menu.buildFromTemplate(_menuTemplate);
|
|
};
|
|
|
|
class TrayStore extends NylasStore {
|
|
|
|
constructor(platform) {
|
|
super();
|
|
this._platform = platform;
|
|
|
|
this._unreadIcon = NativeImage.createFromPath(UNREAD_ICON_PATH);
|
|
this._unreadString = +(UnreadBadgeStore.count()).toLocaleString();
|
|
this._baseIcon = NativeImage.createFromPath(BASE_ICON_PATH);
|
|
this._menu = _buildMenu();
|
|
this._icon = this._getIconImg();
|
|
|
|
this.listenTo(UnreadBadgeStore, this._onUnreadCountChanged);
|
|
}
|
|
|
|
icon() {
|
|
return this._icon;
|
|
}
|
|
|
|
tooltip() {
|
|
return `${this._unreadString} unread messages`;
|
|
}
|
|
|
|
menu() {
|
|
return this._menu;
|
|
}
|
|
|
|
_getIconImg() {
|
|
const imgHandlers = {
|
|
'darwin': ()=> {
|
|
const img = new Image();
|
|
// toDataUrl always returns the @1x image data, so the assets/darwin/
|
|
// contains an "@2x" image /without/ the @2x extension
|
|
img.src = this._baseIcon.toDataURL();
|
|
const canvas = canvasWithSystemTrayIconAndText(img, this._unreadString);
|
|
const pngData = NativeImage.createFromDataURL(canvas.toDataURL()).toPng();
|
|
|
|
// creating from a buffer allows us to specify that the image is @2x
|
|
const out2x = NativeImage.createFromBuffer(pngData, 2);
|
|
out2x.setTemplateImage(true);
|
|
return out2x;
|
|
},
|
|
'default': ()=> {
|
|
return this._unreadString !== '0' ? this._unreadIcon : this._baseIcon;
|
|
},
|
|
};
|
|
|
|
return imgHandlers[this._platform in imgHandlers ? this._platform : 'default']();
|
|
}
|
|
|
|
_onUnreadCountChanged() {
|
|
this._unreadString = +(UnreadBadgeStore.count()).toLocaleString();
|
|
this._icon = this._getIconImg();
|
|
this.trigger();
|
|
}
|
|
}
|
|
|
|
export default TrayStore;
|