|
8 | 8 | } from '@theia/core/electron-shared/electron';
|
9 | 9 | import { fork } from 'node:child_process';
|
10 | 10 | import { AddressInfo } from 'node:net';
|
| 11 | +import { format as logFormat } from 'node:util'; |
11 | 12 | import { join, isAbsolute, resolve } from 'node:path';
|
12 | 13 | import { promises as fs, rm, rmSync } from 'node:fs';
|
13 | 14 | import type { MaybePromise, Mutable } from '@theia/core/lib/common/types';
|
@@ -39,6 +40,7 @@ import {
|
39 | 40 | CHANNEL_SHOW_PLOTTER_WINDOW,
|
40 | 41 | isShowPlotterWindowParams,
|
41 | 42 | } from '../../electron-common/electron-arduino';
|
| 43 | +import { ChildProcess } from 'child_process'; |
42 | 44 |
|
43 | 45 | app.commandLine.appendSwitch('disable-http-cache');
|
44 | 46 |
|
@@ -493,6 +495,11 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
493 | 495 | args,
|
494 | 496 | await this.getForkOptions()
|
495 | 497 | );
|
| 498 | + // In production, the electron main's `console` must be rebind, and delegate all log messages to the Theia backend via IPC. |
| 499 | + // Otherwise, any error that happens in this process won't be in the log files. |
| 500 | + if (!environment.electron.isDevMode()) { |
| 501 | + forwardConsoleTo(backendProcess); |
| 502 | + } |
496 | 503 | console.log(`Starting backend process. PID: ${backendProcess.pid}`);
|
497 | 504 | return new Promise((resolve, reject) => {
|
498 | 505 | // The backend server main file is also supposed to send the resolved http(s) server port via IPC.
|
@@ -777,3 +784,26 @@ function updateAppInfo(
|
777 | 784 | });
|
778 | 785 | return toUpdate;
|
779 | 786 | }
|
| 787 | + |
| 788 | +// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 789 | +type ConsoleLogFunction = (message?: any, ...optionalParams: any[]) => void; |
| 790 | +const consoleLogFunctionNames = [ |
| 791 | + 'log', |
| 792 | + 'trace', |
| 793 | + 'debug', |
| 794 | + 'info', |
| 795 | + 'warn', |
| 796 | + 'error', |
| 797 | +] as const; |
| 798 | +function forwardConsoleTo(child: ChildProcess) { |
| 799 | + for (const name of consoleLogFunctionNames) { |
| 800 | + const original = <ConsoleLogFunction>console[name as keyof Console]; |
| 801 | + console[name] = function () { |
| 802 | + // eslint-disable-next-line prefer-rest-params |
| 803 | + const messages = Object.values(arguments); |
| 804 | + const message = logFormat(...messages); |
| 805 | + child.send({ severity: name, message }); |
| 806 | + original(message); |
| 807 | + }; |
| 808 | + } |
| 809 | +} |
0 commit comments