@futdevpro/nts-dynamo 1.15.153 → 1.15.154

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.
Files changed (46) hide show
  1. package/README.md +18 -3
  2. package/__documentations/2026-08-22-content-free-process-error-boundary.md +91 -0
  3. package/build/_models/control-models/app-params.control-model.d.ts.map +1 -1
  4. package/build/_models/control-models/app-params.control-model.js +1 -2
  5. package/build/_models/control-models/app-params.control-model.js.map +1 -1
  6. package/build/_modules/server/index.d.ts +4 -0
  7. package/build/_modules/server/index.d.ts.map +1 -1
  8. package/build/_modules/server/index.js +5 -0
  9. package/build/_modules/server/index.js.map +1 -1
  10. package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.d.ts +9 -0
  11. package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.d.ts.map +1 -0
  12. package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.js +13 -0
  13. package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.js.map +1 -0
  14. package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.d.ts +20 -0
  15. package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.d.ts.map +1 -0
  16. package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.js +24 -0
  17. package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.js.map +1 -0
  18. package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.d.ts +19 -0
  19. package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.d.ts.map +1 -0
  20. package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.js +83 -0
  21. package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.js.map +1 -0
  22. package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.d.ts +19 -0
  23. package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.d.ts.map +1 -0
  24. package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.js +3 -0
  25. package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.js.map +1 -0
  26. package/build/_services/core/global.service.d.ts +3 -3
  27. package/build/_services/core/global.service.d.ts.map +1 -1
  28. package/build/_services/core/global.service.js +24 -18
  29. package/build/_services/core/global.service.js.map +1 -1
  30. package/build/_services/server/app.server.d.ts +2 -0
  31. package/build/_services/server/app.server.d.ts.map +1 -1
  32. package/build/_services/server/app.server.js +71 -199
  33. package/build/_services/server/app.server.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/_models/control-models/app-params.control-model.spec.ts +23 -19
  36. package/src/_models/control-models/app-params.control-model.ts +10 -9
  37. package/src/_modules/server/index.ts +8 -2
  38. package/src/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.ts +8 -0
  39. package/src/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.ts +19 -0
  40. package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.spec.ts +124 -0
  41. package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.ts +99 -0
  42. package/src/_modules/server/safe-diagnostic/safe-diagnostic.interface.ts +20 -0
  43. package/src/_modules/server/server-status/db-readiness-probe.control-service.spec.ts +2 -2
  44. package/src/_services/core/global.service.ts +55 -54
  45. package/src/_services/server/app-safe-diagnostic.spec.ts +124 -0
  46. package/src/_services/server/app.server.ts +294 -347
@@ -66,8 +66,13 @@ import { DyNTS_GlobalService } from '../core/global.service';
66
66
  import { DyNTS_CollectionGrowthMonitor } from '../core/collection-growth-monitor.service';
67
67
  import { DyNTS_MemoryGuard } from '../core/memory-guard.service';
68
68
  import { DyNTS_EventLoopDiag } from '../core/event-loop-diag.service';
69
- import { DyNTS_RoutingModule } from '../route/routing-module.service';
70
- import { DyNTS_getStarRoute } from '../../_collections/star.controller';
69
+ import { DyNTS_RoutingModule } from '../route/routing-module.service';
70
+ import { DyNTS_getStarRoute } from '../../_collections/star.controller';
71
+ import { DyNTS_SafeDiagnosticStage_Type } from '../../_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum';
72
+ import { DyNTS_SafeDiagnostic_Interface } from '../../_modules/server/safe-diagnostic/safe-diagnostic.interface';
73
+ import {
74
+ DyNTS_SafeDiagnostic_ControlService
75
+ } from '../../_modules/server/safe-diagnostic/safe-diagnostic.control-service';
71
76
 
72
77
  /**
73
78
  *
@@ -343,107 +348,78 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
343
348
  }
344
349
  get fnLogs(): boolean {
345
350
  return DyNTS_global_settings.log_settings.functions;
346
- }
347
- debugLog: boolean = DyNTS_global_settings.log_settings.server_debug;
348
-
349
- constructor(/* extended?: boolean */){
351
+ }
352
+ debugLog: boolean = DyNTS_global_settings.log_settings.server_debug;
353
+
354
+ private reportSafeDiagnostic(
355
+ code: string,
356
+ stage: DyNTS_SafeDiagnosticStage_Type,
357
+ error?: unknown,
358
+ status: number = 500
359
+ ): DyNTS_SafeDiagnostic_Interface {
360
+ const configuredPrefix: string | undefined = DyNTS_global_settings.systemShortCodeName;
361
+ const prefix: string = configuredPrefix && /^[A-Z][A-Z0-9_-]{1,31}$/.test(configuredPrefix)
362
+ ? configuredPrefix
363
+ : 'DYNTS';
364
+
365
+ return DyNTS_SafeDiagnostic_ControlService.report({
366
+ code: `${prefix}|${code}`,
367
+ stage: stage,
368
+ error: error,
369
+ status: status,
370
+ });
371
+ }
372
+
373
+ private forwardSafeDiagnostic(diagnostic: DyNTS_SafeDiagnostic_Interface): void {
374
+ try {
375
+ const pending: Promise<void> | undefined = DyNTS_GlobalService.globalErrorHandler?.(
376
+ DyNTS_SafeDiagnostic_ControlService.toError(diagnostic)
377
+ );
378
+
379
+ void pending?.catch((error: unknown): void => {
380
+ this.reportSafeDiagnostic(
381
+ 'DYNTS-AS0-GLOBAL-HANDLER-REJECTED',
382
+ DyNTS_SafeDiagnosticStage_Type.globalErrorHandler,
383
+ error
384
+ );
385
+ });
386
+ } catch (error) {
387
+ this.reportSafeDiagnostic(
388
+ 'DYNTS-AS0-GLOBAL-HANDLER-THREW',
389
+ DyNTS_SafeDiagnosticStage_Type.globalErrorHandler,
390
+ error
391
+ );
392
+ }
393
+ }
394
+
395
+ constructor(/* extended?: boolean */){
350
396
  super();
351
397
 
352
398
  /* dotenv.config() */
353
399
 
354
- process.on(
355
- 'unhandledRejection',
356
- (reason_theError: object, p_passWhatIsThis_maybeThePromise: any): void => {
357
- if (reason_theError instanceof DyFM_Error) {
358
- reason_theError.logSimple('Unhandled Rejection');
359
- } else {
360
- DyFM_Log.H_error(
361
- 'Unhandled Rejection:', (p_passWhatIsThis_maybeThePromise as Promise<any>)?.toString(),
362
- '\n Rejection reason:', (reason_theError as Error)?.stack?.split('at')?.[0],
363
- /* '\n ErrorCode:', (reason as any)?.code, */
364
- '\n\n Stack:',
365
- (reason_theError as Error)?.stack?.replaceAll?.('\n at', '\n at'),
366
- );
367
- }
368
-
369
- try {
370
- DyNTS_GlobalService.globalErrorHandler?.(
371
- new DyFM_Error({
372
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-BASE-UR`,
373
- message:
374
- `Unhandled Rejection!: "${(reason_theError as Error)?.stack?.split('at')?.[0]}"`,
375
- userMessage: this.defaultErrorUserMsg,
376
- addECToUserMsg: true,
377
- error: reason_theError as Error,
378
- additionalContent: {
379
- reason: reason_theError,
380
- rejectedPromise: p_passWhatIsThis_maybeThePromise,
381
- },
382
- systemVersion: DyNTS_global_settings.systemVersion,
383
- level: DyFM_ErrorLevel.critical,
384
- })
385
- );
386
- } catch (error) {
387
- DyFM_Log.error('globalErrorHandler (MULTILEVEL) ERROR:', error);
388
- }
389
- }
390
- );
391
-
392
- this.asyncConstruct(/* extended */).catch((error: any): void => {
393
- if (error instanceof DyFM_Error) {
394
- if (error.additionalContent?.constructErrors?.length) {
395
- error.additionalContent.constructErrors.forEach((errorItem: DyFM_Error): void => {
396
- DyFM_Error.logSimple('(constructor asyncConstruct.catch) error:', errorItem);
397
- /* if (errorItem instanceof DyFM_Error) {
398
- errorItem.logSimple(`(constructor asyncConstruct.catch) error:\n`);
399
- } else {
400
- DyFM_Log.H_warn(
401
- '(constructor asyncConstruct.catch) additional error content:\n',
402
- errorItem
403
- );
404
- } */
405
- });
406
- } else {
407
- DyFM_Log.H_warn(
408
- '(constructor asyncConstruct.catch) additional error content:\n',
409
- error?.additionalContent
410
- );
411
- }
412
- }
413
-
414
- DyFM_Error.logSimple('(constructor asyncConstruct.catch) error:', error);
415
- /* if (
416
- !DyNTS_global_settings.log_settings.highDetailedLogs &&
417
- (error instanceof DyFM_Error)
418
- ) {
419
- error.logSimple(
420
- `Application: "${this.params?.name}" start failed. (constructor asyncConstruct.catch)` +
421
- '\n all error messages (from this stack):\n\n"' +
422
- error._messages.join('"\n\n"') + '"\n\n'
423
- );
424
- } else if (error instanceof DyFM_Error) {
425
- DyFM_Log.H_error(
426
- `Application: "${this.params?.name}" start failed. (constructor asyncConstruct.catch)`,
427
- `\n ERROR:`, error
428
- );
429
- } */
430
-
431
- const message: string =
432
- (error as DyFM_Error)?.additionalContent?.constructErrors?.flatMap(
433
- (errorItem: DyFM_Error): string[] => {
434
- return errorItem?._messages ?? [];
435
- }
436
- )?.join?.('\n') ??
437
- (error as DyFM_Error)?.errors?.flatMap(
438
- (errorItem: DyFM_AnyError): string[] =>
439
- (errorItem as DyFM_Error)?._messages ?? [ (errorItem as Error)?.message ]
440
- )?.join?.('\n') ??
441
- error?.message ??
442
- 'UNKNOWN';
443
-
444
- DyFM_Log.testError('Application start failed:\n', message);
445
-
446
- process.exit(1);
400
+ process.on(
401
+ 'unhandledRejection',
402
+ (reason: unknown): void => {
403
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
404
+ 'DYNTS-AS0-BASE-UR',
405
+ DyNTS_SafeDiagnosticStage_Type.unhandledRejection,
406
+ reason
407
+ );
408
+
409
+ this.forwardSafeDiagnostic(diagnostic);
410
+ }
411
+ );
412
+
413
+ this.asyncConstruct(/* extended */).catch((error: unknown): void => {
414
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
415
+ 'DYNTS-AS0-BOOTSTRAP-FAILED',
416
+ DyNTS_SafeDiagnosticStage_Type.bootstrap,
417
+ error
418
+ );
419
+
420
+ this.forwardSafeDiagnostic(diagnostic);
421
+
422
+ process.exit(1);
447
423
  });
448
424
  }
449
425
 
@@ -579,12 +555,17 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
579
555
  this._rootServices = await this.getRootServices();
580
556
  }
581
557
 
582
- if (this.postProcess) {
583
- await this.postProcess().catch((error: any): void => {
584
- DyFM_Error.logSimple(`"${this._params.name}" postProcess failed:`, error);
585
- DyNTS_GlobalService.globalErrorHandler?.(error);
586
- });
587
- }
558
+ if (this.postProcess) {
559
+ await this.postProcess().catch((error: unknown): void => {
560
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
561
+ 'DYNTS-AS0-POST-PROCESS-FAILED',
562
+ DyNTS_SafeDiagnosticStage_Type.postProcess,
563
+ error
564
+ );
565
+
566
+ this.forwardSafeDiagnostic(diagnostic);
567
+ });
568
+ }
588
569
 
589
570
  // FR-193 — bedrock OOM korai-figyelmeztetés: feltelepítjük a heap-watchdogot, ha
590
571
  // engedélyezve (DyNTS_global_settings.memoryGuard.enabled, default true). Biztonságos:
@@ -594,17 +575,25 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
594
575
  if (DyNTS_global_settings.memoryGuard?.enabled) {
595
576
  DyNTS_MemoryGuard.getInstance().install();
596
577
  }
597
- } catch (memoryGuardError: unknown) {
598
- DyFM_Log.warn('[DyNTS_MemoryGuard] auto-install skipped (non-fatal):', memoryGuardError);
599
- }
578
+ } catch (memoryGuardError: unknown) {
579
+ this.reportSafeDiagnostic(
580
+ 'DYNTS-AS0-MEMORY-GUARD-SKIPPED',
581
+ DyNTS_SafeDiagnosticStage_Type.memoryGuard,
582
+ memoryGuardError
583
+ );
584
+ }
600
585
 
601
586
  // BFR-OVERSEER-007 — event-loop-lag diag a MemoryGuard MELLÉ: a „process él, HTTP néma" wedge
602
587
  // belső mérése (natív histogram, olcsó). Observation-only, sosem dob; a /server/diag olvas belőle.
603
588
  try {
604
589
  DyNTS_EventLoopDiag.getInstance().install();
605
- } catch (eventLoopDiagError: unknown) {
606
- DyFM_Log.warn('[DyNTS_EventLoopDiag] auto-install skipped (non-fatal):', eventLoopDiagError);
607
- }
590
+ } catch (eventLoopDiagError: unknown) {
591
+ this.reportSafeDiagnostic(
592
+ 'DYNTS-AS0-EVENT-LOOP-DIAG-SKIPPED',
593
+ DyNTS_SafeDiagnosticStage_Type.eventLoopDiagnostic,
594
+ eventLoopDiagError
595
+ );
596
+ }
608
597
 
609
598
  // FR-258 / SR-4 — proactive collection-growth monitor (companion to the MemoryGuard). Warns
610
599
  // into the Errors-sink when a collection grows unbounded, BEFORE it can be loaded into heap and
@@ -613,9 +602,13 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
613
602
  if (DyNTS_global_settings.collectionGrowthMonitor?.enabled) {
614
603
  DyNTS_CollectionGrowthMonitor.getInstance().install();
615
604
  }
616
- } catch (cgmError: unknown) {
617
- DyFM_Log.warn('[DyNTS_CollectionGrowthMonitor] auto-install skipped (non-fatal):', cgmError);
618
- }
605
+ } catch (cgmError: unknown) {
606
+ this.reportSafeDiagnostic(
607
+ 'DYNTS-AS0-COLLECTION-GROWTH-MONITOR-SKIPPED',
608
+ DyNTS_SafeDiagnosticStage_Type.collectionGrowthMonitor,
609
+ cgmError
610
+ );
611
+ }
619
612
 
620
613
  if (!extended) {
621
614
  await this.ready();
@@ -627,26 +620,10 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
627
620
  /* DyFM_Log.info(`NTS Version: ${this.ntsVersion}`); */
628
621
  DyFM_Log.H_success(`${this.params.name} started successfully.`);
629
622
  }
630
- } catch (error) {
631
- this.constructErrors.push(error);
632
-
633
- if (this.deepLog) {
634
- if (DyNTS_global_settings.log_settings.highDetailedLogs) {
635
- DyFM_Log.H_error(
636
- `"${this._params.name}" start failed (in asyncConstruct (highDetailedLog)). `,
637
- `\n\n construct ERRORS:`, this.constructErrors,
638
- '\n\nlast error:', error
639
- );
640
- } else {
641
- DyFM_Log.H_error(
642
- `"${this._params.name}" start failed (in asyncConstruct). `,
643
- `\n\n construct ERRORS:`, this.getSimplifiedConstructErrors(),
644
- '\n\nlast error:', error instanceof DyFM_Error ? error.getErrorSimplified() : error
645
- );
646
- }
647
- }
648
-
649
- throw new DyFM_Error({
623
+ } catch (error) {
624
+ this.constructErrors.push(error);
625
+
626
+ throw new DyFM_Error({
650
627
  ...this._getDefaultErrorSettings('asyncConstruct', error),
651
628
 
652
629
  errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-001`,
@@ -671,22 +648,14 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
671
648
  await DyFM_Async.delay(100);
672
649
 
673
650
  let ready: boolean = false;
674
- const start: number = +new Date();
675
-
676
- if (this.constructErrors.length) {
677
- if (this.deepLog) {
678
- if (DyNTS_global_settings.log_settings.highDetailedLogs) {
679
- DyFM_Log.H_error(
680
- `"${this._params.name}" start failed. (ready; constructErrors check 1)`,
681
- `\n construct ERRORS:`, this.constructErrors
682
- );
683
- } else {
684
- DyFM_Log.H_error(
685
- `"${this._params.name}" start failed. (ready; constructErrors check 1)`,
686
- `\n construct ERRORS:`, this.getSimplifiedConstructErrors(),
687
- );
688
- }
689
- }
651
+ const start: number = +new Date();
652
+
653
+ if (this.constructErrors.length) {
654
+ this.reportSafeDiagnostic(
655
+ 'DYNTS-AS0-READINESS-CONSTRUCT-ERROR',
656
+ DyNTS_SafeDiagnosticStage_Type.readiness,
657
+ this.constructErrors[0]
658
+ );
690
659
 
691
660
  throw new DyFM_Error({
692
661
  ...this._getDefaultErrorSettings(
@@ -709,29 +678,19 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
709
678
  this.systemControls.httpServer.getIsReady() &&
710
679
  this.systemControls.httpsServer.getIsReady()
711
680
  );
712
- } else {
713
- DyFM_Log.error(`"${this._params.name}" APP NOT INITIALIZED while trying to get ready.`);
714
- }
681
+ }
715
682
 
716
683
  if (!ready) {
717
684
  await DyFM_Async.wait(100);
718
685
  }
719
686
  }
720
687
 
721
- if (timeout < +new Date() - start) {
722
- if (this.deepLog) {
723
- if (DyNTS_global_settings.log_settings.highDetailedLogs) {
724
- DyFM_Log.H_error(
725
- `"${this._params.name}" start failed. (ready; TIMEOUT check)`,
726
- `\n construct ERRORS:`, this.constructErrors
727
- );
728
- } else {
729
- DyFM_Log.H_error(
730
- `"${this._params.name}" start failed. (ready; TIMEOUT check)`,
731
- `\n construct ERRORS:`, this.getSimplifiedConstructErrors(),
732
- );
733
- }
734
- }
688
+ if (timeout < +new Date() - start) {
689
+ this.reportSafeDiagnostic(
690
+ 'DYNTS-AS0-READINESS-TIMEOUT',
691
+ DyNTS_SafeDiagnosticStage_Type.readiness,
692
+ this.constructErrors[0] ?? new Error('readiness-timeout')
693
+ );
735
694
 
736
695
  throw new DyFM_Error({
737
696
  ...this._getDefaultErrorSettings(
@@ -752,20 +711,12 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
752
711
  });
753
712
  }
754
713
 
755
- if (this.constructErrors.length) {
756
- if (this.deepLog) {
757
- if (DyNTS_global_settings.log_settings.highDetailedLogs) {
758
- DyFM_Log.H_error(
759
- `"${this._params.name}" start failed. (ready; constructErrors check 2)`,
760
- `\n construct ERRORS:`, this.constructErrors
761
- );
762
- } else {
763
- DyFM_Log.H_error(
764
- `"${this._params.name}" start failed. (ready; constructErrors check 2)`,
765
- `\n construct ERRORS:`, this.getSimplifiedConstructErrors(),
766
- );
767
- }
768
- }
714
+ if (this.constructErrors.length) {
715
+ this.reportSafeDiagnostic(
716
+ 'DYNTS-AS0-READINESS-LATE-CONSTRUCT-ERROR',
717
+ DyNTS_SafeDiagnosticStage_Type.readiness,
718
+ this.constructErrors[0]
719
+ );
769
720
 
770
721
  throw new DyFM_Error({
771
722
  ...this._getDefaultErrorSettings(
@@ -802,7 +753,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
802
753
  msg += `\nHTTPS Server start failed.`;
803
754
  }
804
755
 
805
- DyFM_Log.error(msg, this.constructErrors);
756
+ this.reportSafeDiagnostic(
757
+ 'DYNTS-AS0-READINESS-UNKNOWN',
758
+ DyNTS_SafeDiagnosticStage_Type.readiness,
759
+ this.constructErrors[0] ?? new Error('readiness-unknown')
760
+ );
806
761
 
807
762
  throw new DyFM_Error({
808
763
  ...this._getDefaultErrorSettings('ready', new Error(msg)),
@@ -973,9 +928,9 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
973
928
  this.systemControls.mongoose.init = true;
974
929
 
975
930
  this.mongoose.connection
976
- .once('open', (): void => {
977
- this.systemControls.mongoose.started = true;
978
- DyFM_Log.success(`\nConnected to MongoDB (${this._params.dbUri})\n`);
931
+ .once('open', (): void => {
932
+ this.systemControls.mongoose.started = true;
933
+ DyFM_Log.success('\nConnected to MongoDB.\n');
979
934
 
980
935
  resolve();
981
936
 
@@ -1000,43 +955,27 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1000
955
  // beállítja a started flag-et, így a runtime DB-műveletek elindulnak.
1001
956
  this.systemControls.mongoose.init = false;
1002
957
 
1003
- const d_error: DyFM_Error = new DyFM_Error({
1004
- ...this._getDefaultErrorSettings('startDB', error),
1005
-
1006
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB1`,
1007
- message: `Unable to connect to MongoDB server (${this._params.dbUri}), ` +
1008
- `ERROR: ${error}`,
1009
- level: DyFM_ErrorLevel.serious,
1010
- });
1011
-
1012
- DyFM_Log.H_error(
1013
- `\nUnable to connect to MongoDB server (${this._params.dbUri}).` +
1014
- `\nServer will continue WITHOUT DB connection.` +
1015
- `\nDB-using endpoints will fail at runtime until connection recovers.`
1016
- );
1017
-
1018
- if (this.debugLog) DyFM_Log.S_error(
1019
- `\nMongoDB connect ERROR: `,
1020
- error
1021
- );
1022
-
1023
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1024
-
1025
- resolve();
1026
-
1027
- } else {
1028
- if (this.debugLog) DyFM_Log.error('\nMongoDB ERROR: ', error);
1029
-
1030
- const d_error: DyFM_Error = new DyFM_Error({
1031
- ...this._getDefaultErrorSettings('mongoose.connection.on(error)', error),
1032
-
1033
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB2`,
1034
- message: `MongoDB ERROR: ${error}`,
1035
- level: DyFM_ErrorLevel.critical,
1036
- });
1037
-
1038
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1039
- }
958
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
959
+ 'DYNTS-AS0-SDB1',
960
+ DyNTS_SafeDiagnosticStage_Type.databaseConnect,
961
+ error,
962
+ 503
963
+ );
964
+
965
+ this.forwardSafeDiagnostic(diagnostic);
966
+
967
+ resolve();
968
+
969
+ } else {
970
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
971
+ 'DYNTS-AS0-SDB2',
972
+ DyNTS_SafeDiagnosticStage_Type.databaseRuntime,
973
+ error,
974
+ 503
975
+ );
976
+
977
+ this.forwardSafeDiagnostic(diagnostic);
978
+ }
1040
979
  });
1041
980
 
1042
981
  try {
@@ -1078,10 +1017,22 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1078
1017
  await this.mongoose.disconnect().catch((): void => undefined);
1079
1018
  await this.mongoose.connect(this._params.dbUri, this._params.dbOptions);
1080
1019
  },
1081
- log: (msg: string): void => DyFM_Log.warn(msg),
1082
- });
1083
- } catch (guardErr) {
1084
- DyFM_Log.warn(`[mongo-reconnect-guard] failed to start (non-fatal): ${guardErr instanceof Error ? guardErr.message : String(guardErr)}`);
1020
+ log: (msg: string): void => {
1021
+ this.reportSafeDiagnostic(
1022
+ 'DYNTS-AS0-MONGO-RECONNECT-EVENT',
1023
+ DyNTS_SafeDiagnosticStage_Type.mongoReconnectGuard,
1024
+ msg,
1025
+ 503
1026
+ );
1027
+ },
1028
+ });
1029
+ } catch (guardErr) {
1030
+ this.reportSafeDiagnostic(
1031
+ 'DYNTS-AS0-MONGO-RECONNECT-FAILED',
1032
+ DyNTS_SafeDiagnosticStage_Type.mongoReconnectGuard,
1033
+ guardErr,
1034
+ 503
1035
+ );
1085
1036
  }
1086
1037
  }
1087
1038
 
@@ -1125,30 +1076,32 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1125
1076
  `${Math.round(ttlSeconds / 86400)}d (${ttlSeconds}s)`,
1126
1077
  );
1127
1078
  }
1128
- } else if (action === 'differs') {
1129
- // Live index has a different TTL — left untouched at boot (see ensureRetentionTtlIndex doc).
1130
- DyFM_Log.warn(
1131
- `[FR-258 retention] "${dataName}" already has a {__created} index with a DIFFERENT TTL than the ` +
1132
- `declared ${Math.round(ttlSeconds / 86400)}d (${ttlSeconds}s) — left as-is (no boot-time rebuild). ` +
1133
- `Apply the change via maintenance if intended.`,
1134
- );
1135
- }
1136
- } catch (idxErr: unknown) {
1137
- DyFM_Log.warn(
1138
- `[FR-258 retention] TTL index on "${dataName}" failed (non-fatal): ` +
1139
- `${idxErr instanceof Error ? idxErr.message : String(idxErr)}`,
1140
- );
1079
+ } else if (action === 'differs') {
1080
+ // Live index has a different TTL — left untouched at boot (see ensureRetentionTtlIndex doc).
1081
+ this.reportSafeDiagnostic(
1082
+ 'DYNTS-AS0-RETENTION-INDEX-DIFFERS',
1083
+ DyNTS_SafeDiagnosticStage_Type.retention,
1084
+ new Error('retention-index-differs')
1085
+ );
1086
+ }
1087
+ } catch (idxErr: unknown) {
1088
+ this.reportSafeDiagnostic(
1089
+ 'DYNTS-AS0-RETENTION-INDEX-FAILED',
1090
+ DyNTS_SafeDiagnosticStage_Type.retention,
1091
+ idxErr
1092
+ );
1141
1093
  }
1142
1094
  }
1143
1095
 
1144
1096
  if (ensured > 0) {
1145
1097
  DyFM_Log.success(`[FR-258 retention] ${ensured} TTL index(es) ensured (auto-retention active).`);
1146
1098
  }
1147
- } catch (err: unknown) {
1148
- DyFM_Log.warn(
1149
- `[FR-258 retention] TTL-installer failed (non-fatal): ` +
1150
- `${err instanceof Error ? err.message : String(err)}`,
1151
- );
1099
+ } catch (err: unknown) {
1100
+ this.reportSafeDiagnostic(
1101
+ 'DYNTS-AS0-RETENTION-INSTALLER-FAILED',
1102
+ DyNTS_SafeDiagnosticStage_Type.retention,
1103
+ err
1104
+ );
1152
1105
  }
1153
1106
  }
1154
1107
 
@@ -1223,7 +1176,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1223
1176
  errorStack.splice(1, 2);
1224
1177
  error.stack = errorStack.join('\n');
1225
1178
 
1226
- DyFM_Log.error(errorMsg);
1179
+ this.reportSafeDiagnostic(
1180
+ 'DYNTS-AS0-OPEN-ROUTE-CONFIGURATION',
1181
+ DyNTS_SafeDiagnosticStage_Type.routing,
1182
+ error
1183
+ );
1227
1184
 
1228
1185
  throw error;
1229
1186
  }
@@ -1269,7 +1226,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1269
1226
  errorStack.splice(1, 2);
1270
1227
  error.stack = errorStack.join('\n');
1271
1228
 
1272
- DyFM_Log.error(errorMsg);
1229
+ this.reportSafeDiagnostic(
1230
+ 'DYNTS-AS0-SECURE-ROUTE-CONFIGURATION',
1231
+ DyNTS_SafeDiagnosticStage_Type.routing,
1232
+ error
1233
+ );
1273
1234
 
1274
1235
  throw error;
1275
1236
  }
@@ -1358,9 +1319,14 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1358
1319
  );
1359
1320
 
1360
1321
  resolve();
1361
- })
1362
- .on('error', (error): void => {
1363
- if (this.debugLog) DyFM_Log.error(`\nHTTPS (secure) server ERROR`, error);
1322
+ })
1323
+ .on('error', (error: unknown): void => {
1324
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1325
+ 'DYNTS-AS0-HTTPS-ERROR',
1326
+ DyNTS_SafeDiagnosticStage_Type.httpsServer,
1327
+ error,
1328
+ 503
1329
+ );
1364
1330
 
1365
1331
  if (!this.systemControls.httpsServer.started) {
1366
1332
  const d_error: DyFM_Error = new DyFM_Error({
@@ -1368,41 +1334,26 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1368
1334
 
1369
1335
  errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE1`,
1370
1336
  message: `HTTPS (secure) start server ERROR`,
1371
- });
1372
-
1373
- this.constructErrors.push(d_error);
1374
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1337
+ });
1338
+
1339
+ this.constructErrors.push(d_error);
1340
+ this.forwardSafeDiagnostic(diagnostic);
1375
1341
 
1376
1342
  reject(d_error);
1377
1343
 
1378
- } else {
1379
- const d_error: DyFM_Error = new DyFM_Error({
1380
- ...this._getDefaultErrorSettings('httpsServer.on(error)', error),
1381
-
1382
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE2`,
1383
- message: `HTTPS (secure) server ERROR`,
1384
- level: DyFM_ErrorLevel.serious,
1385
- });
1386
-
1387
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1388
- }
1389
- })
1390
- .on('uncaughtException', (exception): void => {
1391
- const d_error: DyFM_Error = new DyFM_Error({
1392
- ...this._getDefaultErrorSettings('httpsServer.on(uncaughtException)', exception),
1393
-
1394
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE3`,
1395
- message: `HTTPS (secure) server uncaughtException`,
1396
- level: DyFM_ErrorLevel.critical,
1397
- });
1398
-
1399
- if (this.debugLog) DyFM_Log.warn(
1400
- `\nHTTPS (secure) server uncaughtException`,
1401
- d_error
1402
- );
1403
-
1404
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1405
- });
1344
+ } else {
1345
+ this.forwardSafeDiagnostic(diagnostic);
1346
+ }
1347
+ })
1348
+ .on('uncaughtException', (exception): void => {
1349
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1350
+ 'DYNTS-AS0-HTTPS-UNCAUGHT',
1351
+ DyNTS_SafeDiagnosticStage_Type.httpsServer,
1352
+ exception
1353
+ );
1354
+
1355
+ this.forwardSafeDiagnostic(diagnostic);
1356
+ });
1406
1357
  });
1407
1358
  }
1408
1359
 
@@ -1434,8 +1385,13 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1434
1385
  resolve();
1435
1386
  }
1436
1387
  )
1437
- .on('error', (error): void => {
1438
- if (this.debugLog) DyFM_Log.error(`\nHTTP (open) server ERROR`, error);
1388
+ .on('error', (error: unknown): void => {
1389
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1390
+ 'DYNTS-AS0-HTTP-ERROR',
1391
+ DyNTS_SafeDiagnosticStage_Type.httpServer,
1392
+ error,
1393
+ 503
1394
+ );
1439
1395
 
1440
1396
  if (!this.systemControls.httpServer.started) {
1441
1397
  const d_error: DyFM_Error = new DyFM_Error({
@@ -1445,38 +1401,24 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1445
1401
  message: `HTTP (open) start server ERROR`,
1446
1402
  });
1447
1403
 
1448
- this.constructErrors.push(d_error);
1449
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1404
+ this.constructErrors.push(d_error);
1405
+ this.forwardSafeDiagnostic(diagnostic);
1450
1406
 
1451
1407
  reject(d_error);
1452
1408
 
1453
- } else {
1454
- const d_error: DyFM_Error = new DyFM_Error({
1455
- ...this._getDefaultErrorSettings('httpServer.on(error)', error),
1456
-
1457
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE4`,
1458
- message: `HTTP (open) server ERROR`,
1459
- level: DyFM_ErrorLevel.serious,
1460
- });
1461
-
1462
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1463
- }
1464
- })
1465
- .on('uncaughtException', (exception): void => {
1466
- const d_error: DyFM_Error = new DyFM_Error({
1467
- ...this._getDefaultErrorSettings('httpServer.on(uncaughtException)', exception),
1468
-
1469
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE5`,
1470
- message: `HTTP (open) server uncaughtException`,
1471
- level: DyFM_ErrorLevel.critical,
1472
- });
1473
-
1474
- if (this.debugLog) {
1475
- DyFM_Log.warn(`\nHTTP (open) server uncaughtException`, d_error);
1476
- }
1477
-
1478
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1479
- });
1409
+ } else {
1410
+ this.forwardSafeDiagnostic(diagnostic);
1411
+ }
1412
+ })
1413
+ .on('uncaughtException', (exception): void => {
1414
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1415
+ 'DYNTS-AS0-HTTP-UNCAUGHT',
1416
+ DyNTS_SafeDiagnosticStage_Type.httpServer,
1417
+ exception
1418
+ );
1419
+
1420
+ this.forwardSafeDiagnostic(diagnostic);
1421
+ });
1480
1422
  });
1481
1423
  }
1482
1424
  } catch (error) {
@@ -1491,42 +1433,39 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1491
1433
  /**
1492
1434
  *
1493
1435
  */
1494
- private async expressErrorHandling(error, req, res, next): Promise<void> {
1495
- try {
1496
- if (error) {
1497
- const d_error: DyFM_Error = new DyFM_Error({
1498
- ...this._getDefaultErrorSettings('expressErrorHandling', error),
1499
-
1500
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-EEH1`,
1501
- message: `Express ERROR`,
1502
- additionalContent: {
1503
- req,
1504
- res,
1505
- },
1506
- level: DyFM_ErrorLevel.error,
1507
- });
1508
-
1509
- await DyNTS_GlobalService.globalErrorHandler?.(d_error, req, res);
1436
+ private async expressErrorHandling(error, req, res, next): Promise<void> {
1437
+ try {
1438
+ if (error) {
1439
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1440
+ 'DYNTS-AS0-EXPRESS-ERROR',
1441
+ DyNTS_SafeDiagnosticStage_Type.expressFallback,
1442
+ error
1443
+ );
1444
+
1445
+ this.forwardSafeDiagnostic(diagnostic);
1510
1446
 
1511
1447
  // Kliens-safe strip (BFR-FDPAUTHSERVICE-002): az express-error út eddig NYERS error-t küldött
1512
1448
  // (0 strip) — DyFM-nél belső stack/verzió/issuer, axios-jellegű error-nál akár auth-header is
1513
- // kimehetett. A strip-szabályok SSOT-ja a DyNTS_ClientSafeError_Util.
1514
- res.send(DyNTS_ClientSafeError_Util.toClientSafe(error))
1515
- } else {
1516
- DyFM_Log.H_error(
1517
- 'WTF??? express error; without error?...' +
1518
- '\nerr:', error,
1519
- '\nreq:', req,
1520
- '\nres:', res
1521
- );
1522
- }
1523
- } catch (error) {
1524
- DyFM_Log.H_error(
1525
- 'MULTILEVEL ERROR (expressErrorHandling)....' +
1526
- '\n', error
1527
- );
1528
- }
1529
- }
1449
+ // kimehetett. A strip-szabályok SSOT-ja a DyNTS_ClientSafeError_Util.
1450
+ res.send(DyNTS_ClientSafeError_Util.toClientSafe(error))
1451
+ } else {
1452
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1453
+ 'DYNTS-AS0-EXPRESS-MISSING-ERROR',
1454
+ DyNTS_SafeDiagnosticStage_Type.expressFallback
1455
+ );
1456
+
1457
+ this.forwardSafeDiagnostic(diagnostic);
1458
+ }
1459
+ } catch (error) {
1460
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1461
+ 'DYNTS-AS0-EXPRESS-MULTILEVEL',
1462
+ DyNTS_SafeDiagnosticStage_Type.expressFallback,
1463
+ error
1464
+ );
1465
+
1466
+ this.forwardSafeDiagnostic(diagnostic);
1467
+ }
1468
+ }
1530
1469
 
1531
1470
  /**
1532
1471
  *
@@ -1568,7 +1507,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1568
1507
  error.stack = errorStack.join('\n'); */
1569
1508
  error.stack = module.stackLocation;
1570
1509
 
1571
- DyFM_Log.S_error(`ROUTE DUPLICATION: ${module.route}`, error);
1510
+ this.reportSafeDiagnostic(
1511
+ 'DYNTS-AS0-SECURE-ROUTE-DUPLICATION',
1512
+ DyNTS_SafeDiagnosticStage_Type.routing,
1513
+ error
1514
+ );
1572
1515
 
1573
1516
  throw new DyFM_Error({
1574
1517
  ...this._getDefaultErrorSettings('mountSecureRoutes', error),
@@ -1629,7 +1572,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1629
1572
  error.stack = errorStack.join('\n'); */
1630
1573
  error.stack = module.stackLocation;
1631
1574
 
1632
- DyFM_Log.S_error(`ROUTE DUPLICATION: ${module.route}`, error);
1575
+ this.reportSafeDiagnostic(
1576
+ 'DYNTS-AS0-OPEN-ROUTE-DUPLICATION',
1577
+ DyNTS_SafeDiagnosticStage_Type.routing,
1578
+ error
1579
+ );
1633
1580
 
1634
1581
  throw new DyFM_Error({
1635
1582
  ...this._getDefaultErrorSettings('mountOpenRoutes', error),