@futdevpro/nts-dynamo 1.15.153 → 1.15.155

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 (52) hide show
  1. package/README.md +25 -6
  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/build/_services/shared.static-service.d.ts +11 -4
  35. package/build/_services/shared.static-service.d.ts.map +1 -1
  36. package/build/_services/shared.static-service.js +26 -6
  37. package/build/_services/shared.static-service.js.map +1 -1
  38. package/package.json +15 -9
  39. package/src/_models/control-models/app-params.control-model.spec.ts +9 -5
  40. package/src/_models/control-models/app-params.control-model.ts +4 -3
  41. package/src/_modules/server/index.ts +6 -0
  42. package/src/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.ts +8 -0
  43. package/src/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.ts +19 -0
  44. package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.spec.ts +124 -0
  45. package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.ts +99 -0
  46. package/src/_modules/server/safe-diagnostic/safe-diagnostic.interface.ts +20 -0
  47. package/src/_modules/server/server-status/db-readiness-probe.control-service.spec.ts +2 -2
  48. package/src/_services/core/global.service.ts +34 -33
  49. package/src/_services/server/app-safe-diagnostic.spec.ts +124 -0
  50. package/src/_services/server/app.server.ts +209 -262
  51. package/src/_services/shared.static-service.spec.ts +57 -23
  52. package/src/_services/shared.static-service.ts +48 -19
@@ -68,6 +68,11 @@ import { DyNTS_MemoryGuard } from '../core/memory-guard.service';
68
68
  import { DyNTS_EventLoopDiag } from '../core/event-loop-diag.service';
69
69
  import { DyNTS_RoutingModule } from '../route/routing-module.service';
70
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
  *
@@ -346,6 +351,47 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
346
351
  }
347
352
  debugLog: boolean = DyNTS_global_settings.log_settings.server_debug;
348
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
+
349
395
  constructor(/* extended?: boolean */){
350
396
  super();
351
397
 
@@ -353,95 +399,25 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
353
399
 
354
400
  process.on(
355
401
  '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
- }
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
+ );
368
408
 
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
- }
409
+ this.forwardSafeDiagnostic(diagnostic);
389
410
  }
390
411
  );
391
412
 
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';
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
+ );
443
419
 
444
- DyFM_Log.testError('Application start failed:\n', message);
420
+ this.forwardSafeDiagnostic(diagnostic);
445
421
 
446
422
  process.exit(1);
447
423
  });
@@ -580,9 +556,14 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
580
556
  }
581
557
 
582
558
  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);
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);
586
567
  });
587
568
  }
588
569
 
@@ -595,7 +576,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
595
576
  DyNTS_MemoryGuard.getInstance().install();
596
577
  }
597
578
  } catch (memoryGuardError: unknown) {
598
- DyFM_Log.warn('[DyNTS_MemoryGuard] auto-install skipped (non-fatal):', memoryGuardError);
579
+ this.reportSafeDiagnostic(
580
+ 'DYNTS-AS0-MEMORY-GUARD-SKIPPED',
581
+ DyNTS_SafeDiagnosticStage_Type.memoryGuard,
582
+ memoryGuardError
583
+ );
599
584
  }
600
585
 
601
586
  // BFR-OVERSEER-007 — event-loop-lag diag a MemoryGuard MELLÉ: a „process él, HTTP néma" wedge
@@ -603,7 +588,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
603
588
  try {
604
589
  DyNTS_EventLoopDiag.getInstance().install();
605
590
  } catch (eventLoopDiagError: unknown) {
606
- DyFM_Log.warn('[DyNTS_EventLoopDiag] auto-install skipped (non-fatal):', eventLoopDiagError);
591
+ this.reportSafeDiagnostic(
592
+ 'DYNTS-AS0-EVENT-LOOP-DIAG-SKIPPED',
593
+ DyNTS_SafeDiagnosticStage_Type.eventLoopDiagnostic,
594
+ eventLoopDiagError
595
+ );
607
596
  }
608
597
 
609
598
  // FR-258 / SR-4 — proactive collection-growth monitor (companion to the MemoryGuard). Warns
@@ -614,7 +603,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
614
603
  DyNTS_CollectionGrowthMonitor.getInstance().install();
615
604
  }
616
605
  } catch (cgmError: unknown) {
617
- DyFM_Log.warn('[DyNTS_CollectionGrowthMonitor] auto-install skipped (non-fatal):', cgmError);
606
+ this.reportSafeDiagnostic(
607
+ 'DYNTS-AS0-COLLECTION-GROWTH-MONITOR-SKIPPED',
608
+ DyNTS_SafeDiagnosticStage_Type.collectionGrowthMonitor,
609
+ cgmError
610
+ );
618
611
  }
619
612
 
620
613
  if (!extended) {
@@ -630,22 +623,6 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
630
623
  } catch (error) {
631
624
  this.constructErrors.push(error);
632
625
 
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
626
  throw new DyFM_Error({
650
627
  ...this._getDefaultErrorSettings('asyncConstruct', error),
651
628
 
@@ -674,19 +651,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
674
651
  const start: number = +new Date();
675
652
 
676
653
  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
- }
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,8 +678,6 @@ 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) {
@@ -719,19 +686,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
719
686
  }
720
687
 
721
688
  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
- }
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(
@@ -753,19 +712,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
753
712
  }
754
713
 
755
714
  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
- }
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)),
@@ -975,7 +930,7 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
975
930
  this.mongoose.connection
976
931
  .once('open', (): void => {
977
932
  this.systemControls.mongoose.started = true;
978
- DyFM_Log.success(`\nConnected to MongoDB (${this._params.dbUri})\n`);
933
+ DyFM_Log.success('\nConnected to MongoDB.\n');
979
934
 
980
935
  resolve();
981
936
 
@@ -1000,42 +955,26 @@ 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.`
958
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
959
+ 'DYNTS-AS0-SDB1',
960
+ DyNTS_SafeDiagnosticStage_Type.databaseConnect,
961
+ error,
962
+ 503
1016
963
  );
1017
964
 
1018
- if (this.debugLog) DyFM_Log.S_error(
1019
- `\nMongoDB connect ERROR: `,
1020
- error
1021
- );
1022
-
1023
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
965
+ this.forwardSafeDiagnostic(diagnostic);
1024
966
 
1025
967
  resolve();
1026
968
 
1027
969
  } 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
- });
970
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
971
+ 'DYNTS-AS0-SDB2',
972
+ DyNTS_SafeDiagnosticStage_Type.databaseRuntime,
973
+ error,
974
+ 503
975
+ );
1037
976
 
1038
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
977
+ this.forwardSafeDiagnostic(diagnostic);
1039
978
  }
1040
979
  });
1041
980
 
@@ -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),
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
+ },
1082
1028
  });
1083
1029
  } catch (guardErr) {
1084
- DyFM_Log.warn(`[mongo-reconnect-guard] failed to start (non-fatal): ${guardErr instanceof Error ? guardErr.message : String(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
 
@@ -1127,16 +1078,17 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1127
1078
  }
1128
1079
  } else if (action === 'differs') {
1129
1080
  // 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.`,
1081
+ this.reportSafeDiagnostic(
1082
+ 'DYNTS-AS0-RETENTION-INDEX-DIFFERS',
1083
+ DyNTS_SafeDiagnosticStage_Type.retention,
1084
+ new Error('retention-index-differs')
1134
1085
  );
1135
1086
  }
1136
1087
  } 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)}`,
1088
+ this.reportSafeDiagnostic(
1089
+ 'DYNTS-AS0-RETENTION-INDEX-FAILED',
1090
+ DyNTS_SafeDiagnosticStage_Type.retention,
1091
+ idxErr
1140
1092
  );
1141
1093
  }
1142
1094
  }
@@ -1145,9 +1097,10 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1145
1097
  DyFM_Log.success(`[FR-258 retention] ${ensured} TTL index(es) ensured (auto-retention active).`);
1146
1098
  }
1147
1099
  } catch (err: unknown) {
1148
- DyFM_Log.warn(
1149
- `[FR-258 retention] TTL-installer failed (non-fatal): ` +
1150
- `${err instanceof Error ? err.message : String(err)}`,
1100
+ this.reportSafeDiagnostic(
1101
+ 'DYNTS-AS0-RETENTION-INSTALLER-FAILED',
1102
+ DyNTS_SafeDiagnosticStage_Type.retention,
1103
+ err
1151
1104
  );
1152
1105
  }
1153
1106
  }
@@ -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
  }
@@ -1359,8 +1320,13 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1359
1320
 
1360
1321
  resolve();
1361
1322
  })
1362
- .on('error', (error): void => {
1363
- if (this.debugLog) DyFM_Log.error(`\nHTTPS (secure) server ERROR`, error);
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({
@@ -1371,37 +1337,22 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1371
1337
  });
1372
1338
 
1373
1339
  this.constructErrors.push(d_error);
1374
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1340
+ this.forwardSafeDiagnostic(diagnostic);
1375
1341
 
1376
1342
  reject(d_error);
1377
1343
 
1378
1344
  } 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);
1345
+ this.forwardSafeDiagnostic(diagnostic);
1388
1346
  }
1389
1347
  })
1390
1348
  .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
1349
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1350
+ 'DYNTS-AS0-HTTPS-UNCAUGHT',
1351
+ DyNTS_SafeDiagnosticStage_Type.httpsServer,
1352
+ exception
1402
1353
  );
1403
1354
 
1404
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1355
+ this.forwardSafeDiagnostic(diagnostic);
1405
1356
  });
1406
1357
  });
1407
1358
  }
@@ -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({
@@ -1446,36 +1402,22 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1446
1402
  });
1447
1403
 
1448
1404
  this.constructErrors.push(d_error);
1449
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1405
+ this.forwardSafeDiagnostic(diagnostic);
1450
1406
 
1451
1407
  reject(d_error);
1452
1408
 
1453
1409
  } 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);
1410
+ this.forwardSafeDiagnostic(diagnostic);
1463
1411
  }
1464
1412
  })
1465
1413
  .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
- }
1414
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1415
+ 'DYNTS-AS0-HTTP-UNCAUGHT',
1416
+ DyNTS_SafeDiagnosticStage_Type.httpServer,
1417
+ exception
1418
+ );
1477
1419
 
1478
- DyNTS_GlobalService.globalErrorHandler?.(d_error);
1420
+ this.forwardSafeDiagnostic(diagnostic);
1479
1421
  });
1480
1422
  });
1481
1423
  }
@@ -1494,37 +1436,34 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1494
1436
  private async expressErrorHandling(error, req, res, next): Promise<void> {
1495
1437
  try {
1496
1438
  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
- });
1439
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1440
+ 'DYNTS-AS0-EXPRESS-ERROR',
1441
+ DyNTS_SafeDiagnosticStage_Type.expressFallback,
1442
+ error
1443
+ );
1508
1444
 
1509
- await DyNTS_GlobalService.globalErrorHandler?.(d_error, req, res);
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
1449
  // kimehetett. A strip-szabályok SSOT-ja a DyNTS_ClientSafeError_Util.
1514
1450
  res.send(DyNTS_ClientSafeError_Util.toClientSafe(error))
1515
1451
  } else {
1516
- DyFM_Log.H_error(
1517
- 'WTF??? express error; without error?...' +
1518
- '\nerr:', error,
1519
- '\nreq:', req,
1520
- '\nres:', res
1452
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1453
+ 'DYNTS-AS0-EXPRESS-MISSING-ERROR',
1454
+ DyNTS_SafeDiagnosticStage_Type.expressFallback
1521
1455
  );
1456
+
1457
+ this.forwardSafeDiagnostic(diagnostic);
1522
1458
  }
1523
1459
  } catch (error) {
1524
- DyFM_Log.H_error(
1525
- 'MULTILEVEL ERROR (expressErrorHandling)....' +
1526
- '\n', error
1460
+ const diagnostic: DyNTS_SafeDiagnostic_Interface = this.reportSafeDiagnostic(
1461
+ 'DYNTS-AS0-EXPRESS-MULTILEVEL',
1462
+ DyNTS_SafeDiagnosticStage_Type.expressFallback,
1463
+ error
1527
1464
  );
1465
+
1466
+ this.forwardSafeDiagnostic(diagnostic);
1528
1467
  }
1529
1468
  }
1530
1469
 
@@ -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),