Skip to content

Commit 3394581

Browse files
committed
📝 [docs] Add comprehensive Electron-Log and Electron-Updater docs
- Introduces detailed documentation for Electron-Log, covering error handling, event logging, extending functionality, initialization in renderer, migration between major versions, and all transport options and formats - Adds full Electron-Updater documentation, including setup, configuration, events, staged rollouts, compatibility, and advanced usage patterns - Aims to improve developer onboarding and clarify best practices for logging and auto-update workflows in Electron apps
1 parent 4c7a035 commit 3394581

10 files changed

Lines changed: 1336 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Catching errors
2+
3+
electron-log can be used to collect all unhandled errors/rejections
4+
5+
To initialize catching, call the `log.errorHandler.startCatching` method. It
6+
should be done in both main and renderer processes if you want to collect logs
7+
on both sides.
8+
9+
#### `log.errorHandler.startCatching(options?)`
10+
11+
Start catching
12+
13+
#### `log.errorHandler.stopCatching()`
14+
15+
Stop error catching
16+
17+
#### `log.errorHandler.handle(error, options?)`
18+
19+
Process an error. Works even if catching isn't started.
20+
21+
## Options
22+
23+
#### `showDialog` {boolean}
24+
25+
Default: `true`
26+
27+
It follows Electron logic for error handling, so the dialog is
28+
shown only when error is thrown in the main process. Errors from a renderer
29+
process and any rejected promises are ignored. Settings it to false disables
30+
error dialog for any error.
31+
32+
#### `onError({ createIssue, error, processType, versions }) => void | false`
33+
34+
Default: `null`
35+
36+
Attach a custom error handler. If the handler returns false, this error will
37+
not be processed. In a renderer process only the `error` property available.
38+
39+
`createIssue(url, queryParams)` Open the url with query params appended in a
40+
browser
41+
42+
`error: Error` - handled error
43+
44+
`processType: 'browser' | 'renderer`
45+
46+
`version: { app: string, electron: string, os: string }` - Version information
47+
which could be useful for an error report
48+
49+
50+
51+
## Github issue example
52+
53+
```js
54+
log.errorHandler.startCatching({
55+
showDialog: false,
56+
onError({ createIssue, error, processType, versions }) {
57+
if (processType === 'renderer') {
58+
return;
59+
}
60+
61+
electron.dialog.showMessageBox({
62+
title: 'An error occurred',
63+
message: error.message,
64+
detail: error.stack,
65+
type: 'error',
66+
buttons: ['Ignore', 'Report', 'Exit'],
67+
})
68+
.then((result) => {
69+
if (result.response === 1) {
70+
createIssue('https://github.com/my-acc/my-app/issues/new', {
71+
title: `Error report for ${versions.app}`,
72+
body: 'Error:\n```' + error.stack + '\n```\n' + `OS: ${versions.os}`
73+
});
74+
return;
75+
}
76+
77+
if (result.response === 2) {
78+
electron.app.quit();
79+
}
80+
});
81+
}
82+
});
83+
```
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Save electron events
2+
3+
Sometimes it's helpful to save critical electron events to the log file.
4+
5+
`log.eventLogger.startLogging(options?)`;
6+
7+
By default, it saves the following events:
8+
- `certificate-error`, `child-process-gone`, `render-process-gone` of `app`
9+
- `crashed`, `gpu-process-crashed` of `webContents`
10+
- `did-fail-load`, `did-fail-provisional-load`, `plugin-crashed`,
11+
`preload-error` of every WebContents. You can switch any event on/off.
12+
13+
## Methods
14+
15+
#### `log.eventLogger.startLogging(options?: EventLoggerOptions)`
16+
17+
Start saving event logs.
18+
19+
#### `log.eventLogger.stopLogging()`
20+
21+
Stop saving logs.
22+
23+
#### `log.eventLogger.setOptions(options: EventLoggerOptions)`
24+
25+
Set logging options.
26+
27+
## Options
28+
29+
#### `log.eventLogger.format` {string | (input: EventFormatterInput) => any[]}
30+
31+
Default: `'{eventSource}#{eventName}:'`
32+
33+
Custom format function example:
34+
35+
```js
36+
log.eventLogger.format = ({ args, event, eventName, eventSource }) => {
37+
return [`${eventSource}#${eventName}:`, JSON.stringify(args)];
38+
};
39+
```
40+
41+
#### `log.eventLogger.formatters` {object}
42+
43+
A set of functions which formats a specific event.
44+
45+
```js
46+
log.eventLogger.formatters.webContents['console-message'] = ({
47+
args: [level, message, line, sourceId],
48+
event,
49+
eventName,
50+
eventSource
51+
}) => {
52+
const webContents = event.sender;
53+
54+
if (level > 2) {
55+
return undefined;
56+
}
57+
58+
return { message, source: `${sourceId}:${line}`, url: webContents?.getURL() };
59+
};
60+
```
61+
62+
#### `log.eventLogger.events` {object}
63+
64+
Allow switching specific events on/off easily
65+
66+
Default:
67+
68+
```js
69+
log.eventLogger.events = {
70+
app: {
71+
'certificate-error': true,
72+
'child-process-gone': true,
73+
'render-process-gone': true,
74+
},
75+
webContents: {
76+
'did-fail-load': true,
77+
'did-fail-provisional-load': true,
78+
'plugin-crashed': true,
79+
'preload-error': true,
80+
'unresponsive': true,
81+
}
82+
}
83+
```
84+
85+
#### `log.eventLogger.level` {LogLevel}
86+
87+
Which log level is used for logging
88+
89+
Default: `'warn'`
90+
91+
#### `log.eventLogger.scope` {LogLevel}
92+
93+
Which log scope is used for logging
94+
95+
Default: `''`
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Extending electron-log
2+
3+
Each process in Electron has its own electron-log instance, so make sure you
4+
define a custom transport or hook in each process. It's a good idea to save
5+
such a code in a separated file and require it from inside each process.
6+
7+
## Transport
8+
9+
Transport is just a function `(msg: LogMessage) => void`, so you can override
10+
it or add your own transport.
11+
12+
```js
13+
import util from 'util';
14+
15+
log.transports.console = (message) => {
16+
const text = util.format.apply(util, message.data);
17+
console.log(`[${message.date.toLocaleTimeString()} ${message.level}] ${text}`);
18+
};
19+
```
20+
21+
Please be aware, if you override a transport function, the default
22+
transport options (like level or format) will be undefined.
23+
24+
### Transforms
25+
26+
Each transport has a `transform` option which is an array of functions. Before
27+
doing some work, a log message is passed through each transform function to
28+
format `data` before processing.
29+
30+
A transform has the following interface:
31+
32+
```typescript
33+
({ data, message, logger, transport }) => any;
34+
```
35+
36+
It returns a message `data` property with some transformations applied.
37+
38+
Example of adding a custom transform function
39+
40+
```js
41+
log.transports.file.transforms.push(({ data, logger, message, transport }) => {
42+
if (data.join().includes('paynment')) {
43+
return ['[PAYNMENT]', ...data];
44+
}
45+
46+
return data;
47+
});
48+
```
49+
50+
## Hooks
51+
52+
In some situations, you may want to get more control over logging. Hook
53+
is a function called on each transport call.
54+
55+
`(msg: LogMessage, transport: Transport) => LogMessage`
56+
57+
Hook function return original or modified message. If the hook function
58+
returns false, the current transport will be skipped.
59+
60+
In this example, the file transport is disabled for all messages that contain
61+
'password' phrase, and hides token text:
62+
63+
```js
64+
log.hooks.push((message, transport, transportName) => {
65+
if (transportName !== 'file') {
66+
return message;
67+
}
68+
69+
if (message.data.join().includes('password')) {
70+
return false;
71+
}
72+
73+
if (message.data.join().includes('token')) {
74+
return {
75+
...message,
76+
data: message.data.slice(0, 2),
77+
};
78+
}
79+
80+
return message;
81+
});
82+
```
83+
84+
## Log levels
85+
86+
Add a new "notice" level before "info" (index = 2):
87+
88+
```js
89+
log.addLevel('notice', 2);
90+
log.notice('New level added');
91+
```
92+
93+
Also, you can add TypeScript type definition:
94+
95+
*electron-log.extend.d.ts:*
96+
```typescript
97+
import 'electron-log'
98+
99+
declare module 'electron-log' {
100+
interface LogFunctions {
101+
notice(...params: any[]): void;
102+
}
103+
}
104+
105+
```
106+
107+
## LogMessage
108+
109+
- data: any[] Arguments passed to log function
110+
- date: Date
111+
- level: 'error' | 'warn' | 'info' | 'verbose' | 'debug' | 'silly'
112+
- logId: string
113+
- scope: string | undefined
114+
- variables?: { [name: string]: any } When a log message is created,
115+
values from `log.variables` are set as `message.variables` (to make it
116+
- possible to pass these Variables between main and renderer processes)
117+
118+
See more details in [the type definition](../src/index.d.ts#L41)

0 commit comments

Comments
 (0)