@platformatic/basic 2.75.0-alpha.0 → 2.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/config.d.ts CHANGED
@@ -95,6 +95,7 @@ export interface PlatformaticStackable {
95
95
  };
96
96
  startTimeout?: number;
97
97
  restartOnError?: boolean | number;
98
+ exitOnUnhandledErrors?: boolean;
98
99
  gracefulShutdown?: {
99
100
  runtime: number | string;
100
101
  service: number | string;
package/lib/base.js CHANGED
@@ -352,6 +352,7 @@ export class BaseStackable extends EventEmitter {
352
352
  isEntrypoint: this.isEntrypoint,
353
353
  runtimeBasePath: this.runtimeConfig?.basePath ?? null,
354
354
  wantsAbsoluteUrls: meta.composer?.wantsAbsoluteUrls ?? false,
355
+ exitOnUnhandledErrors: this.runtimeConfig.exitOnUnhandledErrors ?? true,
355
356
  /* c8 ignore next 2 - else */
356
357
  port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
357
358
  host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
@@ -416,12 +417,7 @@ export class BaseStackable extends EventEmitter {
416
417
  return
417
418
  }
418
419
 
419
- await collectMetrics(
420
- this.serviceId,
421
- this.workerId,
422
- metricsConfig,
423
- this.metricsRegistry
424
- )
420
+ await collectMetrics(this.serviceId, this.workerId, metricsConfig, this.metricsRegistry)
425
421
  }
426
422
  }
427
423
 
@@ -512,7 +508,7 @@ export class BaseStackable extends EventEmitter {
512
508
  help: 'Number of active resources keeping the event loop alive',
513
509
  registers: [registry]
514
510
  })
515
- globalThis.platformatic.onActiveResourcesEventLoop = (val) => activeResourcesEventLoopMetric.set(val)
511
+ globalThis.platformatic.onActiveResourcesEventLoop = val => activeResourcesEventLoopMetric.set(val)
516
512
  }
517
513
 
518
514
  async #invalidateHttpCache (opts = {}) {
@@ -83,7 +83,7 @@ export class ChildProcess extends ITC {
83
83
  getMetrics: (...args) => {
84
84
  return this.#getMetrics(...args)
85
85
  },
86
- close: (signal) => {
86
+ close: signal => {
87
87
  let handled = false
88
88
 
89
89
  try {
@@ -113,7 +113,11 @@ export class ChildProcess extends ITC {
113
113
 
114
114
  this.listen()
115
115
  this.#setupLogger()
116
- this.#setupHandlers()
116
+
117
+ if (globalThis.platformatic.exitOnUnhandledErrors) {
118
+ this.#setupHandlers()
119
+ }
120
+
117
121
  this.#setupServer()
118
122
  this.#setupInterceptors()
119
123
 
@@ -289,7 +293,7 @@ export class ChildProcess extends ITC {
289
293
  help: 'Number of active resources keeping the event loop alive',
290
294
  registers: [registry]
291
295
  })
292
- globalThis.platformatic.onActiveResourcesEventLoop = (val) => activeResourcesEventLoopMetric.set(val)
296
+ globalThis.platformatic.onActiveResourcesEventLoop = val => activeResourcesEventLoopMetric.set(val)
293
297
  }
294
298
 
295
299
  async #getMetrics ({ format } = {}) {
@@ -406,6 +410,14 @@ export class ChildProcess extends ITC {
406
410
 
407
411
  process.on('uncaughtException', handleUnhandled.bind(this, 'uncaught exception'))
408
412
  process.on('unhandledRejection', handleUnhandled.bind(this, 'unhandled rejection'))
413
+
414
+ process.on('newListener', event => {
415
+ if (event === 'uncaughtException' || event === 'unhandledRejection') {
416
+ this.#logger.warn(
417
+ `A listener has been added for the "process.${event}" event. This listener will be never triggered as Watt default behavior will kill the process before.\n To disable this behavior, set "exitOnUnhandledErrors" to false in the runtime config.`
418
+ )
419
+ }
420
+ })
409
421
  }
410
422
 
411
423
  #notifyConfig (config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/basic",
3
- "version": "2.75.0-alpha.0",
3
+ "version": "2.75.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -24,11 +24,11 @@
24
24
  "split2": "^4.2.0",
25
25
  "undici": "^7.0.0",
26
26
  "ws": "^8.18.0",
27
- "@platformatic/metrics": "2.75.0-alpha.0",
28
- "@platformatic/config": "2.75.0-alpha.0",
29
- "@platformatic/utils": "2.75.0-alpha.0",
30
- "@platformatic/telemetry": "2.75.0-alpha.0",
31
- "@platformatic/itc": "2.75.0-alpha.0"
27
+ "@platformatic/config": "2.75.0",
28
+ "@platformatic/telemetry": "2.75.0",
29
+ "@platformatic/utils": "2.75.0",
30
+ "@platformatic/metrics": "2.75.0",
31
+ "@platformatic/itc": "2.75.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "borp": "^0.20.0",
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/basic/2.75.0-alpha.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/basic/2.75.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Stackable",
5
5
  "type": "object",
@@ -327,6 +327,10 @@
327
327
  }
328
328
  ]
329
329
  },
330
+ "exitOnUnhandledErrors": {
331
+ "default": true,
332
+ "type": "boolean"
333
+ },
330
334
  "gracefulShutdown": {
331
335
  "type": "object",
332
336
  "properties": {
@@ -1,59 +0,0 @@
1
- import { generateRequest, sanitize } from '@platformatic/itc'
2
- import { ensureLoggableError } from '@platformatic/utils'
3
- import { once } from 'node:events'
4
- import { platform } from 'node:os'
5
- import { workerData } from 'node:worker_threads'
6
- import build from 'pino-abstract-transport'
7
- import { WebSocket } from 'ws'
8
- import { getSocketPath } from './child-manager.js'
9
-
10
- /* c8 ignore next 5 */
11
- function logDirectError (message, error) {
12
- process._rawDebug(`Logger thread for child process of service ${workerData.id} ${message}.`, {
13
- error: ensureLoggableError(error)
14
- })
15
- }
16
-
17
- /* c8 ignore next 4 */
18
- function handleUnhandled (type, error) {
19
- logDirectError(`threw an ${type}`, error)
20
- process.exit(6)
21
- }
22
-
23
- process.on('uncaughtException', handleUnhandled.bind(null, 'uncaught exception'))
24
- process.on('unhandledRejection', handleUnhandled.bind(null, 'unhandled rejection'))
25
-
26
- export default async function () {
27
- try {
28
- /* c8 ignore next */
29
- const protocol = platform() === 'win32' ? 'ws+unix:' : 'ws+unix://'
30
- const socket = new WebSocket(`${protocol}${getSocketPath(process.env.PLT_MANAGER_ID)}`)
31
-
32
- await once(socket, 'open')
33
-
34
- // Do not process responses but empty the socket inbound queue
35
- socket.on('message', () => {})
36
-
37
- /* c8 ignore next 3 */
38
- socket.on('error', error => {
39
- logDirectError('threw a socket error', error)
40
- })
41
-
42
- return build(
43
- async function (source) {
44
- for await (const obj of source) {
45
- socket.send(JSON.stringify(sanitize(generateRequest('log', { logs: [obj] }))))
46
- }
47
- },
48
- {
49
- close (_, cb) {
50
- socket.close()
51
- cb()
52
- }
53
- }
54
- )
55
- /* c8 ignore next 3 */
56
- } catch (error) {
57
- logDirectError('threw a connection error', error)
58
- }
59
- }