mirror of
https://github.com/HeyPuter/puter.git
synced 2025-12-16 18:25:21 -06:00
telemetry: config telemetry to run by default (#2184)
This commit is contained in:
76
package-lock.json
generated
76
package-lock.json
generated
@@ -926,7 +926,6 @@
|
||||
"version": "7.28.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
@@ -1247,7 +1246,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -1287,7 +1285,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@@ -3050,7 +3047,6 @@
|
||||
"node_modules/@jimp/custom": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/core": "^0.22.12"
|
||||
}
|
||||
@@ -3081,7 +3077,6 @@
|
||||
"node_modules/@jimp/plugin-blit": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12"
|
||||
},
|
||||
@@ -3092,7 +3087,6 @@
|
||||
"node_modules/@jimp/plugin-blur": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12"
|
||||
},
|
||||
@@ -3113,7 +3107,6 @@
|
||||
"node_modules/@jimp/plugin-color": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12",
|
||||
"tinycolor2": "^1.6.0"
|
||||
@@ -3151,7 +3144,6 @@
|
||||
"node_modules/@jimp/plugin-crop": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12"
|
||||
},
|
||||
@@ -3255,7 +3247,6 @@
|
||||
"node_modules/@jimp/plugin-resize": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12"
|
||||
},
|
||||
@@ -3266,7 +3257,6 @@
|
||||
"node_modules/@jimp/plugin-rotate": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12"
|
||||
},
|
||||
@@ -3280,7 +3270,6 @@
|
||||
"node_modules/@jimp/plugin-scale": {
|
||||
"version": "0.22.12",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12"
|
||||
},
|
||||
@@ -3521,7 +3510,6 @@
|
||||
"node_modules/@opentelemetry/api": {
|
||||
"version": "1.9.0",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
@@ -5239,7 +5227,6 @@
|
||||
"version": "8.48.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.48.0",
|
||||
"@typescript-eslint/types": "8.48.0",
|
||||
@@ -5821,7 +5808,6 @@
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -6401,7 +6387,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.8.25",
|
||||
"caniuse-lite": "^1.0.30001754",
|
||||
@@ -6591,7 +6576,6 @@
|
||||
"node_modules/chai": {
|
||||
"version": "4.5.0",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"assertion-error": "^1.1.0",
|
||||
"check-error": "^1.0.3",
|
||||
@@ -6857,10 +6841,6 @@
|
||||
"resolved": "tools/comment-parser",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/comment-writer": {
|
||||
"resolved": "tools/comment-writer",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"dev": true,
|
||||
@@ -7846,7 +7826,6 @@
|
||||
"node_modules/eslint": {
|
||||
"version": "9.39.1",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -13370,7 +13349,6 @@
|
||||
"version": "8.17.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -14802,7 +14780,6 @@
|
||||
"version": "5.9.3",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -14976,7 +14953,6 @@
|
||||
"version": "7.2.6",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -15068,7 +15044,6 @@
|
||||
"version": "4.0.14",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vitest/expect": "4.0.14",
|
||||
"@vitest/mocker": "4.0.14",
|
||||
@@ -15183,7 +15158,6 @@
|
||||
"version": "5.103.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.7",
|
||||
"@types/estree": "^1.0.8",
|
||||
@@ -15231,7 +15205,6 @@
|
||||
"version": "5.1.4",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@discoveryjs/json-ext": "^0.5.0",
|
||||
"@webpack-cli/configtest": "^2.1.1",
|
||||
@@ -15431,7 +15404,6 @@
|
||||
"node_modules/winston": {
|
||||
"version": "3.18.3",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@colors/colors": "^1.6.0",
|
||||
"@dabh/diagnostics": "^2.0.8",
|
||||
@@ -15549,7 +15521,6 @@
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.3",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
@@ -15741,7 +15712,6 @@
|
||||
"node_modules/zod": {
|
||||
"version": "3.25.76",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
@@ -15768,6 +15738,7 @@
|
||||
"@mistralai/mistralai": "^1.3.4",
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.40.0",
|
||||
"@opentelemetry/exporter-trace-otlp-grpc": "^0.40.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.14.0",
|
||||
"@opentelemetry/sdk-node": "^0.49.1",
|
||||
@@ -15859,7 +15830,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
|
||||
"integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
@@ -15869,7 +15839,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.49.1.tgz",
|
||||
"integrity": "sha512-kaNl/T7WzyMUQHQlVq7q0oV4Kev6+0xFwqzofryC66jgGMacd0QH5TwfpbUwSTby+SdAdprAe5UKMvBw4tKS5Q==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^1.0.0"
|
||||
},
|
||||
@@ -15971,6 +15940,46 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"src/backend/node_modules/@opentelemetry/exporter-metrics-otlp-grpc": {
|
||||
"version": "0.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.40.0.tgz",
|
||||
"integrity": "sha512-1kIEi2G4uVrxqZV+9M09Il2XeylAUOpNXg1vpS50R2CgP99u6ICzu+xhENXWucaVya+tRduwrhkVzSagyP7Mtw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.7.1",
|
||||
"@opentelemetry/core": "1.14.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-http": "0.40.0",
|
||||
"@opentelemetry/otlp-grpc-exporter-base": "0.40.0",
|
||||
"@opentelemetry/otlp-transformer": "0.40.0",
|
||||
"@opentelemetry/resources": "1.14.0",
|
||||
"@opentelemetry/sdk-metrics": "1.14.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"src/backend/node_modules/@opentelemetry/exporter-metrics-otlp-http": {
|
||||
"version": "0.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.40.0.tgz",
|
||||
"integrity": "sha512-4ferfcHOyYAhy+7Xk/vMWGBI6yafeOxpLWKrRjzNFAGKzD78teOnPTvyaCecPF0nviTF4VuwT2ECgon6Q/bFBQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@opentelemetry/core": "1.14.0",
|
||||
"@opentelemetry/otlp-exporter-base": "0.40.0",
|
||||
"@opentelemetry/otlp-transformer": "0.40.0",
|
||||
"@opentelemetry/resources": "1.14.0",
|
||||
"@opentelemetry/sdk-metrics": "1.14.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"src/backend/node_modules/@opentelemetry/exporter-trace-otlp-grpc": {
|
||||
"version": "0.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.40.0.tgz",
|
||||
@@ -17882,7 +17891,7 @@
|
||||
},
|
||||
"src/puter-js": {
|
||||
"name": "@heyputer/puter.js",
|
||||
"version": "2.1.15",
|
||||
"version": "2.2.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@heyputer/kv.js": "^0.2.1"
|
||||
@@ -17990,6 +17999,7 @@
|
||||
},
|
||||
"tools/comment-writer": {
|
||||
"version": "1.0.0",
|
||||
"extraneous": true,
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"axios": "^1.7.8",
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
"@opentelemetry/exporter-trace-otlp-grpc": "^0.40.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.40.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.14.0",
|
||||
"@opentelemetry/sdk-node": "^0.49.1",
|
||||
"@pagerduty/pdjs": "^2.2.4",
|
||||
@@ -105,4 +106,4 @@
|
||||
},
|
||||
"author": "Puter Technologies Inc.",
|
||||
"license": "AGPL-3.0-only"
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class PerfMonModule extends AdvancedBase {
|
||||
async install (context) {
|
||||
const services = context.get('services');
|
||||
|
||||
const TelemetryService = require('./TelemetryService');
|
||||
const { TelemetryService } = require('./TelemetryService');
|
||||
services.registerService('telemetry', TelemetryService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,35 +16,42 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const opentelemetry = require('@opentelemetry/api');
|
||||
const { NodeSDK } = require('@opentelemetry/sdk-node');
|
||||
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
||||
const { PeriodicExportingMetricReader, ConsoleMetricExporter } = require('@opentelemetry/sdk-metrics');
|
||||
import { SpanStatusCode, trace } from '@opentelemetry/api';
|
||||
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { ConsoleMetricExporter, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
||||
import { NodeSDK } from '@opentelemetry/sdk-node';
|
||||
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';
|
||||
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
|
||||
import config from '../../config.js';
|
||||
import BaseService from '../../services/BaseService.js';
|
||||
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
|
||||
|
||||
const { Resource } = require('@opentelemetry/resources');
|
||||
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
||||
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base');
|
||||
const config = require('../../config');
|
||||
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
|
||||
|
||||
const BaseService = require('../../services/BaseService');
|
||||
|
||||
class TelemetryService extends BaseService {
|
||||
export class TelemetryService extends BaseService {
|
||||
/** @type {import('@opentelemetry/api').Tracer} */
|
||||
#tracer = null;
|
||||
_construct () {
|
||||
|
||||
const traceExporter = this.#getConfiguredExporter();
|
||||
const metricExporter = this.#getMetricExporter();
|
||||
|
||||
if ( !traceExporter && !metricExporter ) {
|
||||
console.log('TelemetryService not configured, skipping initialization.');
|
||||
return;
|
||||
}
|
||||
|
||||
const resource = Resource.default().merge(
|
||||
new Resource({
|
||||
[SemanticResourceAttributes.SERVICE_NAME]: 'puter-backend',
|
||||
[SemanticResourceAttributes.SERVICE_VERSION]: '0.1.0',
|
||||
}));
|
||||
|
||||
const exporter = this.#getConfiguredExporter();
|
||||
this.exporter = exporter;
|
||||
|
||||
const sdk = new NodeSDK({
|
||||
resource,
|
||||
traceExporter: exporter,
|
||||
traceExporter: traceExporter,
|
||||
metricReader: new PeriodicExportingMetricReader({
|
||||
exporter: new ConsoleMetricExporter(),
|
||||
exporter: metricExporter,
|
||||
}),
|
||||
instrumentations: [getNodeAutoInstrumentations()],
|
||||
});
|
||||
@@ -53,21 +60,24 @@ class TelemetryService extends BaseService {
|
||||
|
||||
this.sdk.start();
|
||||
|
||||
this.tracer_ = opentelemetry.trace.getTracer('puter-tracer');
|
||||
this.#tracer = trace.getTracer('puter-tracer');
|
||||
|
||||
}
|
||||
|
||||
_init () {
|
||||
if ( ! this.#tracer ) {
|
||||
return;
|
||||
}
|
||||
const svc_context = this.services.get('context');
|
||||
svc_context.register_context_hook('pre_arun', ({ hints, trace_name, callback, replace_callback }) => {
|
||||
if ( ! trace_name ) return;
|
||||
if ( ! hints.trace ) return;
|
||||
console.log('APPLYING TRACE NAME', trace_name);
|
||||
replace_callback(async () => {
|
||||
return await this.tracer_.startActiveSpan(trace_name, async span => {
|
||||
return await this.#tracer.startActiveSpan(trace_name, async span => {
|
||||
try {
|
||||
return await callback();
|
||||
} catch ( error ) {
|
||||
span.setStatus({ code: opentelemetry.SpanStatusCode.ERROR, message: error.message });
|
||||
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
||||
throw error;
|
||||
} finally {
|
||||
span.end();
|
||||
@@ -81,9 +91,17 @@ class TelemetryService extends BaseService {
|
||||
if ( config.jaeger ?? this.config.jaeger ) {
|
||||
return new OTLPTraceExporter(config.jaeger ?? this.config.jaeger);
|
||||
}
|
||||
const exporter = new ConsoleSpanExporter();
|
||||
return exporter;
|
||||
if ( this.config.console ) {
|
||||
return new ConsoleSpanExporter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TelemetryService;
|
||||
#getMetricExporter () {
|
||||
if ( config.jaeger ?? this.config.jaeger ) {
|
||||
return new OTLPMetricExporter(config.jaeger ?? this.config.jaeger);
|
||||
}
|
||||
if ( this.config.console ) {
|
||||
return new ConsoleMetricExporter();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ const surrounding_box = (col, lines) => {
|
||||
const lowest_allowed = Math.max(...ver_info.map(r => r.under));
|
||||
|
||||
// ACTUAL VERSION CHECK
|
||||
const [major, minor] = process.versions.node.split('.').map(Number);
|
||||
const [major, _minor] = process.versions.node.split('.').map(Number);
|
||||
if ( major < lowest_allowed ) {
|
||||
const lines = [];
|
||||
lines.push(`Please use a version of Node.js ${lowest_allowed} or newer.`);
|
||||
@@ -80,7 +80,7 @@ const surrounding_box = (col, lines) => {
|
||||
if ( ! import.meta.filename ) {
|
||||
Object.defineProperty(import.meta, 'filename', {
|
||||
get: () => import.meta.url.slice('file://'.length),
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
@@ -102,7 +102,7 @@ const main = async () => {
|
||||
} = (await import('@heyputer/backend')).default;
|
||||
|
||||
const k = new Kernel({
|
||||
entry_path: import.meta.filename
|
||||
entry_path: import.meta.filename,
|
||||
});
|
||||
for ( const mod of EssentialModules ) {
|
||||
k.add_module(new mod());
|
||||
@@ -117,9 +117,7 @@ const main = async () => {
|
||||
k.add_module(new PuterAIModule());
|
||||
k.add_module(new InternetModule());
|
||||
k.add_module(new DNSModule());
|
||||
if ( process.env.PERFMON ) {
|
||||
k.add_module(new PerfMonModule());
|
||||
}
|
||||
k.add_module(new PerfMonModule());
|
||||
if ( process.env.UNSAFE_PUTER_DEV ) {
|
||||
k.add_module(new DevelopmentModule());
|
||||
}
|
||||
@@ -128,35 +126,35 @@ const main = async () => {
|
||||
|
||||
const early_init_errors = [
|
||||
{
|
||||
text: `Cannot find package '@heyputer/backend'`,
|
||||
text: 'Cannot find package \'@heyputer/backend\'',
|
||||
notes: [
|
||||
'this usually happens if you forget `npm install`'
|
||||
'this usually happens if you forget `npm install`',
|
||||
],
|
||||
suggestions: [
|
||||
'try running `npm install`'
|
||||
'try running `npm install`',
|
||||
],
|
||||
technical_notes: [
|
||||
'@heyputer/backend is in an npm workspace'
|
||||
]
|
||||
'@heyputer/backend is in an npm workspace',
|
||||
],
|
||||
},
|
||||
{
|
||||
text: `Cannot find package`,
|
||||
text: 'Cannot find package',
|
||||
notes: [
|
||||
'this usually happens if you forget `npm install`'
|
||||
'this usually happens if you forget `npm install`',
|
||||
],
|
||||
suggestions: [
|
||||
'try running `npm install`'
|
||||
'try running `npm install`',
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Cannot write to path',
|
||||
notes: [
|
||||
'this usually happens when /var/puter isn\'t chown\'d to the right UID'
|
||||
'this usually happens when /var/puter isn\'t chown\'d to the right UID',
|
||||
],
|
||||
suggestions: [
|
||||
'check issue #645 on our github'
|
||||
]
|
||||
}
|
||||
'check issue #645 on our github',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// null coalescing operator
|
||||
@@ -167,13 +165,13 @@ const nco = (...args) => {
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const _print_error_help = (error_help) => {
|
||||
const lines = [];
|
||||
lines.push(nco(error_help.title, error_help.text));
|
||||
for ( const note of (nco(error_help.notes, [])) ) {
|
||||
lines.push(`📝 ${note}`)
|
||||
lines.push(`📝 ${note}`);
|
||||
}
|
||||
if ( error_help.suggestions ) {
|
||||
lines.push('Suggestions:');
|
||||
@@ -189,14 +187,13 @@ const _print_error_help = (error_help) => {
|
||||
}
|
||||
surrounding_box('31;1', lines);
|
||||
console.error(lines.join('\n'));
|
||||
}
|
||||
};
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await main();
|
||||
} catch (e) {
|
||||
for ( const error_help of early_init_errors ) {
|
||||
const message = e && e.message;
|
||||
if ( e.message && e.message.includes(error_help.text) ) {
|
||||
_print_error_help(error_help);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user