@omnitronix/game-engine-sdk 1.0.4 → 2.0.2
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/CHANGELOG.md +86 -0
- package/MIGRATION.md +126 -0
- package/dist/bootstrap/index.d.ts +4 -1
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +32 -32
- package/dist/common/api-docs/setup-documentation.d.ts +1 -1
- package/dist/common/api-docs/setup-documentation.d.ts.map +1 -1
- package/dist/common/error-handling/all-exceptions.filter.d.ts +0 -3
- package/dist/common/error-handling/all-exceptions.filter.d.ts.map +1 -1
- package/dist/common/error-handling/all-exceptions.filter.js +35 -21
- package/dist/common/error-handling/error-code-mapper.d.ts.map +1 -1
- package/dist/common/error-handling/error-code-mapper.js +15 -70
- package/dist/common/error-handling/internal-error-code.d.ts +13 -59
- package/dist/common/error-handling/internal-error-code.d.ts.map +1 -1
- package/dist/common/error-handling/internal-error-code.js +16 -68
- package/dist/common/logger/logger.d.ts +2 -3
- package/dist/common/logger/logger.d.ts.map +1 -1
- package/dist/common/logger/logger.js +3 -16
- package/dist/common/logger/logging.middleware.d.ts.map +1 -1
- package/dist/common/logger/logging.middleware.js +16 -4
- package/dist/common/metrics/prometheus.service.d.ts +5 -0
- package/dist/common/metrics/prometheus.service.d.ts.map +1 -1
- package/dist/common/metrics/prometheus.service.js +43 -3
- package/dist/common/retry/retry-policy.d.ts.map +1 -1
- package/dist/common/retry/retry-policy.js +9 -4
- package/dist/common/secrets-provider/secrets-provider.aws.d.ts.map +1 -1
- package/dist/common/secrets-provider/secrets-provider.aws.js +2 -1
- package/dist/esm/bootstrap/index.js +33 -33
- package/dist/esm/common/error-handling/all-exceptions.filter.js +36 -22
- package/dist/esm/common/error-handling/error-code-mapper.js +15 -70
- package/dist/esm/common/error-handling/internal-error-code.js +16 -68
- package/dist/esm/common/logger/logger.js +3 -16
- package/dist/esm/common/logger/logging.middleware.js +16 -4
- package/dist/esm/common/metrics/prometheus.service.js +10 -3
- package/dist/esm/common/retry/retry-policy.js +9 -4
- package/dist/esm/common/secrets-provider/secrets-provider.aws.js +2 -1
- package/dist/esm/generated/game-engine-registry_pb.js +5 -11
- package/dist/esm/generated/game-engine_pb.js +10 -24
- package/dist/esm/grpc/connect-router.middleware.js +7 -1
- package/dist/esm/grpc/game-engine.grpc.in-adapter.js +64 -20
- package/dist/esm/health/application/services/health.service.js +33 -39
- package/dist/esm/health/health.module.js +1 -1
- package/dist/esm/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.js +19 -4
- package/dist/esm/registration/adapters/game-engine-registry.grpc.out-adapter.js +3 -4
- package/dist/esm/registration/services/game-engine-auto-register.service.js +11 -8
- package/dist/generated/game-engine-registry_pb.d.ts +5 -5
- package/dist/generated/game-engine-registry_pb.d.ts.map +1 -1
- package/dist/generated/game-engine-registry_pb.js +4 -10
- package/dist/generated/game-engine_pb.d.ts +26 -10
- package/dist/generated/game-engine_pb.d.ts.map +1 -1
- package/dist/generated/game-engine_pb.js +8 -22
- package/dist/grpc/connect-router.middleware.d.ts +9 -1
- package/dist/grpc/connect-router.middleware.d.ts.map +1 -1
- package/dist/grpc/connect-router.middleware.js +7 -1
- package/dist/grpc/game-engine.grpc.in-adapter.d.ts +18 -3
- package/dist/grpc/game-engine.grpc.in-adapter.d.ts.map +1 -1
- package/dist/grpc/game-engine.grpc.in-adapter.js +64 -20
- package/dist/grpc/index.d.ts +1 -1
- package/dist/grpc/index.d.ts.map +1 -1
- package/dist/health/application/ports/out/shutdown.out-port.d.ts +2 -0
- package/dist/health/application/ports/out/shutdown.out-port.d.ts.map +1 -1
- package/dist/health/application/services/health.service.d.ts.map +1 -1
- package/dist/health/application/services/health.service.js +33 -39
- package/dist/health/domain/health.d.ts +1 -1
- package/dist/health/domain/health.d.ts.map +1 -1
- package/dist/health/health.module.js +1 -1
- package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.d.ts +2 -1
- package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.d.ts.map +1 -1
- package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.js +19 -4
- package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.d.ts.map +1 -1
- package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.js +3 -4
- package/dist/registration/services/game-engine-auto-register.service.d.ts.map +1 -1
- package/dist/registration/services/game-engine-auto-register.service.js +11 -8
- package/dist/types.d.ts +6 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -1,67 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes relevant to game engine services.
|
|
3
|
+
*
|
|
4
|
+
* Scoped to game-engine SDK concerns only.
|
|
5
|
+
* Platform-level codes (sessions, operators, jackpots, geo, etc.)
|
|
6
|
+
* belong in the RGS platform, not in individual engine services.
|
|
7
|
+
*/
|
|
1
8
|
export declare enum InternalErrorCode {
|
|
2
|
-
FORBIDDEN = "FORBIDDEN",
|
|
3
|
-
INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR",
|
|
4
|
-
INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
|
|
5
|
-
INVALID_CURRENCY_CODE = "INVALID_CURRENCY_CODE",
|
|
6
|
-
GAME_NOT_FOUND = "GAME_NOT_FOUND",
|
|
7
|
-
GAME_CONFIG_NOT_FOUND = "GAME_CONFIG_NOT_FOUND",
|
|
8
|
-
GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP = "GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP",
|
|
9
|
-
OPERATOR_GAME_NOT_FOUND = "OPERATOR_GAME_NOT_FOUND",
|
|
10
|
-
OPERATOR_GAME_ALREADY_ENABLED = "OPERATOR_GAME_ALREADY_ENABLED",
|
|
11
|
-
INVALID_GAME_CONFIG_DATA = "INVALID_GAME_CONFIG_DATA",
|
|
12
|
-
INVALID_GAME_UPDATE_DATA = "INVALID_GAME_UPDATE_DATA",
|
|
13
|
-
GAME_CODE_ALREADY_EXISTS = "GAME_CODE_ALREADY_EXISTS",
|
|
14
9
|
GAME_ENGINE_ERROR = "GAME_ENGINE_ERROR",
|
|
15
|
-
GAME_OR_GAME_CONFIG_DISABLED = "GAME_OR_GAME_CONFIG_DISABLED",
|
|
16
10
|
DEBUG_COMMANDS_DISABLED = "DEBUG_COMMANDS_DISABLED",
|
|
17
|
-
INVALID_SESSION = "INVALID_SESSION",
|
|
18
|
-
SESSION_NOT_FOUND = "SESSION_NOT_FOUND",
|
|
19
|
-
SESSION_NOT_ACTIVE = "SESSION_NOT_ACTIVE",
|
|
20
|
-
SESSION_MISMATCH = "SESSION_MISMATCH",
|
|
21
|
-
INVALID_STATE_TRANSITION = "INVALID_STATE_TRANSITION",
|
|
22
|
-
INVALID_BET_AMOUNT = "INVALID_BET_AMOUNT",
|
|
23
|
-
REALITY_CHECK_IN_PROGRESS = "REALITY_CHECK_IN_PROGRESS",
|
|
24
|
-
SESSION_TERMINATED = "SESSION_TERMINATED",
|
|
25
|
-
SESSION_CANNOT_BE_TERMINATED = "SESSION_CANNOT_BE_TERMINATED",
|
|
26
|
-
SESSION_AUTO_RESOLVE_FAILED = "SESSION_AUTO_RESOLVE_FAILED",
|
|
27
|
-
SESSION_ALREADY_EXISTS = "SESSION_ALREADY_EXISTS",
|
|
28
|
-
INCOMPATIBLE_GAMEPLAY_CONFIG = "INCOMPATIBLE_GAMEPLAY_CONFIG",
|
|
29
11
|
UNKNOWN_COMMAND = "UNKNOWN_COMMAND",
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
COUNTRY_CODE_RESTRICTED = "COUNTRY_CODE_RESTRICTED",
|
|
12
|
+
INVALID_COMMAND = "INVALID_COMMAND",
|
|
13
|
+
INVALID_RNG_SEED = "INVALID_RNG_SEED",
|
|
14
|
+
INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR",
|
|
15
|
+
FORBIDDEN = "FORBIDDEN",
|
|
35
16
|
UNAUTHORIZED = "UNAUTHORIZED",
|
|
36
|
-
AUTH_VALIDATION_FAILED = "AUTH_VALIDATION_FAILED",
|
|
37
|
-
BALANCE_NOT_FOUND = "BALANCE_NOT_FOUND",
|
|
38
|
-
DEBIT_FAILED = "DEBIT_FAILED",
|
|
39
|
-
CREDIT_FAILED = "CREDIT_FAILED",
|
|
40
|
-
INVALID_AUTH_DATA = "INVALID_AUTH_DATA",
|
|
41
17
|
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
OPERATOR_JURISDICTION_CONFIG_NOT_FOUND = "OPERATOR_JURISDICTION_CONFIG_NOT_FOUND",
|
|
45
|
-
GAME_ROUND_LOG_NOT_FOUND = "GAME_ROUND_LOG_NOT_FOUND",
|
|
46
|
-
COUNTRY_NOT_PERMITTED = "COUNTRY_NOT_PERMITTED",
|
|
47
|
-
GEO_VALIDATION_SERVICE_UNAVAILABLE = "GEO_VALIDATION_SERVICE_UNAVAILABLE",
|
|
48
|
-
RESOURCE_NOT_FOUND = "RESOURCE_NOT_FOUND",
|
|
49
|
-
FINANCIAL_TRANSACTION_NOT_FOUND = "FINANCIAL_TRANSACTION_NOT_FOUND",
|
|
50
|
-
HEALTH_CHECK_FAILED = "HEALTH_CHECK_FAILED",
|
|
51
|
-
JACKPOT_TYPE_NOT_FOUND = "JACKPOT_TYPE_NOT_FOUND",
|
|
52
|
-
JACKPOT_TIER_NOT_FOUND = "JACKPOT_TIER_NOT_FOUND",
|
|
53
|
-
JACKPOT_CONFIGURATION_NOT_FOUND = "JACKPOT_CONFIGURATION_NOT_FOUND",
|
|
54
|
-
JACKPOT_CONFIGURATION_IS_ACTIVE = "JACKPOT_CONFIGURATION_IS_ACTIVE",
|
|
55
|
-
JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED = "JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED",
|
|
56
|
-
JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS = "JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS",
|
|
57
|
-
RNG_SEED_NOT_FOUND = "RNG_SEED_NOT_FOUND",
|
|
58
|
-
RNG_SEED_MISMATCH = "RNG_SEED_MISMATCH",
|
|
59
|
-
MASTER_HASH_INVALID = "MASTER_HASH_INVALID",
|
|
60
|
-
REPLAY_OUTCOME_MISMATCH = "REPLAY_OUTCOME_MISMATCH",
|
|
61
|
-
CONCURRENT_MODIFICATION = "CONCURRENT_MODIFICATION",
|
|
62
|
-
ACCOUNT_LOCKED = "ACCOUNT_LOCKED",
|
|
63
|
-
DAILY_LIMIT_EXCEEDED = "DAILY_LIMIT_EXCEEDED",
|
|
64
|
-
INVALID_AMOUNT = "INVALID_AMOUNT",
|
|
65
|
-
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
|
|
18
|
+
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",
|
|
19
|
+
HEALTH_CHECK_FAILED = "HEALTH_CHECK_FAILED"
|
|
66
20
|
}
|
|
67
21
|
//# sourceMappingURL=internal-error-code.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-error-code.d.ts","sourceRoot":"","sources":["../../../src/common/error-handling/internal-error-code.ts"],"names":[],"mappings":"AAAA,oBAAY,iBAAiB;
|
|
1
|
+
{"version":3,"file":"internal-error-code.d.ts","sourceRoot":"","sources":["../../../src/common/error-handling/internal-error-code.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,oBAAY,iBAAiB;IAE3B,iBAAiB,sBAAsB;IACvC,uBAAuB,4BAA4B;IACnD,eAAe,oBAAoB;IACnC,eAAe,oBAAoB;IAGnC,gBAAgB,qBAAqB;IAGrC,qBAAqB,0BAA0B;IAC/C,SAAS,cAAc;IACvB,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;IAG3C,mBAAmB,wBAAwB;CAC5C"}
|
|
@@ -1,80 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InternalErrorCode = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Error codes relevant to game engine services.
|
|
6
|
+
*
|
|
7
|
+
* Scoped to game-engine SDK concerns only.
|
|
8
|
+
* Platform-level codes (sessions, operators, jackpots, geo, etc.)
|
|
9
|
+
* belong in the RGS platform, not in individual engine services.
|
|
10
|
+
*/
|
|
4
11
|
var InternalErrorCode;
|
|
5
12
|
(function (InternalErrorCode) {
|
|
6
|
-
|
|
7
|
-
InternalErrorCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
8
|
-
InternalErrorCode["INSUFFICIENT_FUNDS"] = "INSUFFICIENT_FUNDS";
|
|
9
|
-
InternalErrorCode["INVALID_CURRENCY_CODE"] = "INVALID_CURRENCY_CODE";
|
|
10
|
-
// Game Catalog errors
|
|
11
|
-
InternalErrorCode["GAME_NOT_FOUND"] = "GAME_NOT_FOUND";
|
|
12
|
-
InternalErrorCode["GAME_CONFIG_NOT_FOUND"] = "GAME_CONFIG_NOT_FOUND";
|
|
13
|
-
InternalErrorCode["GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP"] = "GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP";
|
|
14
|
-
InternalErrorCode["OPERATOR_GAME_NOT_FOUND"] = "OPERATOR_GAME_NOT_FOUND";
|
|
15
|
-
InternalErrorCode["OPERATOR_GAME_ALREADY_ENABLED"] = "OPERATOR_GAME_ALREADY_ENABLED";
|
|
16
|
-
InternalErrorCode["INVALID_GAME_CONFIG_DATA"] = "INVALID_GAME_CONFIG_DATA";
|
|
17
|
-
InternalErrorCode["INVALID_GAME_UPDATE_DATA"] = "INVALID_GAME_UPDATE_DATA";
|
|
18
|
-
InternalErrorCode["GAME_CODE_ALREADY_EXISTS"] = "GAME_CODE_ALREADY_EXISTS";
|
|
13
|
+
// Core game engine errors
|
|
19
14
|
InternalErrorCode["GAME_ENGINE_ERROR"] = "GAME_ENGINE_ERROR";
|
|
20
|
-
InternalErrorCode["GAME_OR_GAME_CONFIG_DISABLED"] = "GAME_OR_GAME_CONFIG_DISABLED";
|
|
21
15
|
InternalErrorCode["DEBUG_COMMANDS_DISABLED"] = "DEBUG_COMMANDS_DISABLED";
|
|
22
|
-
// Game Orchestrator errors
|
|
23
|
-
InternalErrorCode["INVALID_SESSION"] = "INVALID_SESSION";
|
|
24
|
-
InternalErrorCode["SESSION_NOT_FOUND"] = "SESSION_NOT_FOUND";
|
|
25
|
-
InternalErrorCode["SESSION_NOT_ACTIVE"] = "SESSION_NOT_ACTIVE";
|
|
26
|
-
InternalErrorCode["SESSION_MISMATCH"] = "SESSION_MISMATCH";
|
|
27
|
-
InternalErrorCode["INVALID_STATE_TRANSITION"] = "INVALID_STATE_TRANSITION";
|
|
28
|
-
InternalErrorCode["INVALID_BET_AMOUNT"] = "INVALID_BET_AMOUNT";
|
|
29
|
-
InternalErrorCode["REALITY_CHECK_IN_PROGRESS"] = "REALITY_CHECK_IN_PROGRESS";
|
|
30
|
-
InternalErrorCode["SESSION_TERMINATED"] = "SESSION_TERMINATED";
|
|
31
|
-
InternalErrorCode["SESSION_CANNOT_BE_TERMINATED"] = "SESSION_CANNOT_BE_TERMINATED";
|
|
32
|
-
InternalErrorCode["SESSION_AUTO_RESOLVE_FAILED"] = "SESSION_AUTO_RESOLVE_FAILED";
|
|
33
|
-
InternalErrorCode["SESSION_ALREADY_EXISTS"] = "SESSION_ALREADY_EXISTS";
|
|
34
|
-
InternalErrorCode["INCOMPATIBLE_GAMEPLAY_CONFIG"] = "INCOMPATIBLE_GAMEPLAY_CONFIG";
|
|
35
16
|
InternalErrorCode["UNKNOWN_COMMAND"] = "UNKNOWN_COMMAND";
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
InternalErrorCode["
|
|
39
|
-
|
|
40
|
-
InternalErrorCode["
|
|
41
|
-
InternalErrorCode["
|
|
17
|
+
InternalErrorCode["INVALID_COMMAND"] = "INVALID_COMMAND";
|
|
18
|
+
// RNG integrity (GLI-19)
|
|
19
|
+
InternalErrorCode["INVALID_RNG_SEED"] = "INVALID_RNG_SEED";
|
|
20
|
+
// Infrastructure errors
|
|
21
|
+
InternalErrorCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
22
|
+
InternalErrorCode["FORBIDDEN"] = "FORBIDDEN";
|
|
42
23
|
InternalErrorCode["UNAUTHORIZED"] = "UNAUTHORIZED";
|
|
43
|
-
InternalErrorCode["AUTH_VALIDATION_FAILED"] = "AUTH_VALIDATION_FAILED";
|
|
44
|
-
InternalErrorCode["BALANCE_NOT_FOUND"] = "BALANCE_NOT_FOUND";
|
|
45
|
-
InternalErrorCode["DEBIT_FAILED"] = "DEBIT_FAILED";
|
|
46
|
-
InternalErrorCode["CREDIT_FAILED"] = "CREDIT_FAILED";
|
|
47
|
-
InternalErrorCode["INVALID_AUTH_DATA"] = "INVALID_AUTH_DATA";
|
|
48
24
|
InternalErrorCode["VALIDATION_ERROR"] = "VALIDATION_ERROR";
|
|
49
|
-
InternalErrorCode["JURISDICTION_CONFIG_ALREADY_EXISTS"] = "JURISDICTION_CONFIG_ALREADY_EXISTS";
|
|
50
|
-
InternalErrorCode["JURISDICTION_CONFIG_NOT_FOUND"] = "JURISDICTION_CONFIG_NOT_FOUND";
|
|
51
|
-
InternalErrorCode["OPERATOR_JURISDICTION_CONFIG_NOT_FOUND"] = "OPERATOR_JURISDICTION_CONFIG_NOT_FOUND";
|
|
52
|
-
// Game round log errors
|
|
53
|
-
InternalErrorCode["GAME_ROUND_LOG_NOT_FOUND"] = "GAME_ROUND_LOG_NOT_FOUND";
|
|
54
|
-
// Geo Validation errors
|
|
55
|
-
InternalErrorCode["COUNTRY_NOT_PERMITTED"] = "COUNTRY_NOT_PERMITTED";
|
|
56
|
-
InternalErrorCode["GEO_VALIDATION_SERVICE_UNAVAILABLE"] = "GEO_VALIDATION_SERVICE_UNAVAILABLE";
|
|
57
|
-
InternalErrorCode["RESOURCE_NOT_FOUND"] = "RESOURCE_NOT_FOUND";
|
|
58
|
-
// Financial transaction errors
|
|
59
|
-
InternalErrorCode["FINANCIAL_TRANSACTION_NOT_FOUND"] = "FINANCIAL_TRANSACTION_NOT_FOUND";
|
|
60
|
-
//Health check errors
|
|
61
|
-
InternalErrorCode["HEALTH_CHECK_FAILED"] = "HEALTH_CHECK_FAILED";
|
|
62
|
-
//Jackpot errors
|
|
63
|
-
InternalErrorCode["JACKPOT_TYPE_NOT_FOUND"] = "JACKPOT_TYPE_NOT_FOUND";
|
|
64
|
-
InternalErrorCode["JACKPOT_TIER_NOT_FOUND"] = "JACKPOT_TIER_NOT_FOUND";
|
|
65
|
-
InternalErrorCode["JACKPOT_CONFIGURATION_NOT_FOUND"] = "JACKPOT_CONFIGURATION_NOT_FOUND";
|
|
66
|
-
InternalErrorCode["JACKPOT_CONFIGURATION_IS_ACTIVE"] = "JACKPOT_CONFIGURATION_IS_ACTIVE";
|
|
67
|
-
InternalErrorCode["JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED"] = "JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED";
|
|
68
|
-
InternalErrorCode["JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS"] = "JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS";
|
|
69
|
-
// RNG and Replay errors
|
|
70
|
-
InternalErrorCode["RNG_SEED_NOT_FOUND"] = "RNG_SEED_NOT_FOUND";
|
|
71
|
-
InternalErrorCode["RNG_SEED_MISMATCH"] = "RNG_SEED_MISMATCH";
|
|
72
|
-
InternalErrorCode["MASTER_HASH_INVALID"] = "MASTER_HASH_INVALID";
|
|
73
|
-
InternalErrorCode["REPLAY_OUTCOME_MISMATCH"] = "REPLAY_OUTCOME_MISMATCH";
|
|
74
|
-
// Concurrency
|
|
75
|
-
InternalErrorCode["CONCURRENT_MODIFICATION"] = "CONCURRENT_MODIFICATION";
|
|
76
|
-
InternalErrorCode["ACCOUNT_LOCKED"] = "ACCOUNT_LOCKED";
|
|
77
|
-
InternalErrorCode["DAILY_LIMIT_EXCEEDED"] = "DAILY_LIMIT_EXCEEDED";
|
|
78
|
-
InternalErrorCode["INVALID_AMOUNT"] = "INVALID_AMOUNT";
|
|
79
25
|
InternalErrorCode["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
|
|
26
|
+
// Health check
|
|
27
|
+
InternalErrorCode["HEALTH_CHECK_FAILED"] = "HEALTH_CHECK_FAILED";
|
|
80
28
|
})(InternalErrorCode || (exports.InternalErrorCode = InternalErrorCode = {}));
|
|
@@ -10,11 +10,10 @@ export declare class Logger implements NestLoggerService {
|
|
|
10
10
|
private selectFormat;
|
|
11
11
|
private getJsonFormat;
|
|
12
12
|
private getPrettyFormat;
|
|
13
|
-
private safeStringify;
|
|
14
13
|
private getTransports;
|
|
15
|
-
log(message:
|
|
14
|
+
log(message: string, { level, ...rest }?: {
|
|
16
15
|
level?: string;
|
|
17
|
-
} & Record<string,
|
|
16
|
+
} & Record<string, unknown>): void;
|
|
18
17
|
error(message: any, ...optionalParams: any[]): void;
|
|
19
18
|
warn(message: any, ...optionalParams: any[]): void;
|
|
20
19
|
debug(message: any, ...optionalParams: any[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,KAAK,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnC,qBAAa,MAAO,YAAW,iBAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS;IAMlD,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,KAAK,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnC,qBAAa,MAAO,YAAW,iBAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS;IAMlD,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,aAAa;IAUrB,GAAG,CACD,OAAO,EAAE,MAAM,EACf,EAAE,KAAc,EAAE,GAAG,IAAI,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAqBhF,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAsB5C,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI3C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI5C,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;CAG/C"}
|
|
@@ -69,25 +69,12 @@ class Logger {
|
|
|
69
69
|
return output;
|
|
70
70
|
}));
|
|
71
71
|
}
|
|
72
|
-
safeStringify(obj) {
|
|
73
|
-
try {
|
|
74
|
-
return JSON.stringify(obj, (key, value) => {
|
|
75
|
-
if (typeof value === 'bigint') {
|
|
76
|
-
return value.toString();
|
|
77
|
-
}
|
|
78
|
-
return value;
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
catch (_error) {
|
|
82
|
-
return '[Object cannot be serialized]';
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
72
|
getTransports() {
|
|
86
|
-
const
|
|
73
|
+
const consoleTransport = new winston_1.transports.Console();
|
|
87
74
|
if (process.env.LOG_TO_FILE === 'true') {
|
|
88
|
-
|
|
75
|
+
return [consoleTransport, new winston_1.transports.File({ filename: 'logs/app.log' })];
|
|
89
76
|
}
|
|
90
|
-
return
|
|
77
|
+
return [consoleTransport];
|
|
91
78
|
}
|
|
92
79
|
log(message, { level = 'info', ...rest } = {}) {
|
|
93
80
|
switch (level) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logging.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logging.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAwC1D,qBACa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAMhC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY;CAkBpD"}
|
|
@@ -13,11 +13,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.LoggingMiddleware = void 0;
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const logger_1 = require("./logger");
|
|
16
|
-
|
|
16
|
+
/** Endpoints to suppress from logging on success. Configurable via LOG_BLOCKED_ENDPOINTS env var (comma-separated). */
|
|
17
|
+
const BLOCKED_ENDPOINTS = process.env.LOG_BLOCKED_ENDPOINTS
|
|
18
|
+
? process.env.LOG_BLOCKED_ENDPOINTS.split(',').map(e => e.trim())
|
|
19
|
+
: [];
|
|
17
20
|
const SENSITIVE_FIELDS = new Set([
|
|
18
|
-
'password',
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
+
'password',
|
|
22
|
+
'token',
|
|
23
|
+
'secret',
|
|
24
|
+
'authorization',
|
|
25
|
+
'apikey',
|
|
26
|
+
'api_key',
|
|
27
|
+
'accesstoken',
|
|
28
|
+
'refreshtoken',
|
|
29
|
+
'creditcard',
|
|
30
|
+
'ssn',
|
|
31
|
+
'private_key',
|
|
32
|
+
'privatekey',
|
|
21
33
|
]);
|
|
22
34
|
function sanitize(obj) {
|
|
23
35
|
if (obj === null || obj === undefined || typeof obj !== 'object')
|
|
@@ -20,6 +20,11 @@ export declare class PrometheusService implements MetricsPort {
|
|
|
20
20
|
getCounter(name: string): Counter;
|
|
21
21
|
getGauge(name: string): Gauge;
|
|
22
22
|
getHistogram(name: string): Histogram;
|
|
23
|
+
/**
|
|
24
|
+
* Returns Prometheus text format metrics from the default prom-client registry.
|
|
25
|
+
* The @willsoto/nestjs-prometheus module also exposes a /metrics HTTP endpoint
|
|
26
|
+
* automatically — this method is for programmatic access via the MetricsPort.
|
|
27
|
+
*/
|
|
23
28
|
getMetrics(): Promise<string>;
|
|
24
29
|
}
|
|
25
30
|
//# sourceMappingURL=prometheus.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prometheus.service.d.ts","sourceRoot":"","sources":["../../../src/common/metrics/prometheus.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,IAAI,WAAW,EACtB,KAAK,IAAI,SAAS,EAClB,SAAS,IAAI,aAAa,EAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExE,qBACa,iBAAkB,YAAW,WAAW;IAKjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IAExC,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAE/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IA1BnC,OAAO,CAAC,eAAe,CAAmE;gBAIvE,mBAAmB,EAAE,WAAW,EAEhC,iBAAiB,EAAE,WAAW,EAE9B,mBAAmB,EAAE,WAAW,EAEhC,qBAAqB,EAAE,aAAa,EAEpC,iBAAiB,EAAE,SAAS,EAE5B,kBAAkB,EAAE,SAAS,EAE7B,kBAAkB,EAAE,SAAS,EAE7B,4BAA4B,EAAE,WAAW,EAEzC,4BAA4B,EAAE,WAAW,EAEzC,uBAAuB,EAAE,aAAa,EAEtC,8BAA8B,EAAE,WAAW,EAE3C,gBAAgB,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"prometheus.service.d.ts","sourceRoot":"","sources":["../../../src/common/metrics/prometheus.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,IAAI,WAAW,EACtB,KAAK,IAAI,SAAS,EAClB,SAAS,IAAI,aAAa,EAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExE,qBACa,iBAAkB,YAAW,WAAW;IAKjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IAExC,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAE/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IA1BnC,OAAO,CAAC,eAAe,CAAmE;gBAIvE,mBAAmB,EAAE,WAAW,EAEhC,iBAAiB,EAAE,WAAW,EAE9B,mBAAmB,EAAE,WAAW,EAEhC,qBAAqB,EAAE,aAAa,EAEpC,iBAAiB,EAAE,SAAS,EAE5B,kBAAkB,EAAE,SAAS,EAE7B,kBAAkB,EAAE,SAAS,EAE7B,4BAA4B,EAAE,WAAW,EAEzC,4BAA4B,EAAE,WAAW,EAEzC,uBAAuB,EAAE,aAAa,EAEtC,8BAA8B,EAAE,WAAW,EAE3C,gBAAgB,EAAE,aAAa;IAK5C,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpD,OAAO,CAAC,kBAAkB;IAkB1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAQ7B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAQrC;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAIpC"}
|
|
@@ -1,10 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
2
18
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
19
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
20
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
21
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
22
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
23
|
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
8
41
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
42
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
43
|
};
|
|
@@ -33,8 +66,9 @@ let PrometheusService = class PrometheusService {
|
|
|
33
66
|
this.metricsRegistry = new Map();
|
|
34
67
|
this.initializeRegistry();
|
|
35
68
|
}
|
|
36
|
-
initializeMetricsFromDatabase() {
|
|
37
|
-
|
|
69
|
+
async initializeMetricsFromDatabase() {
|
|
70
|
+
// No-op: Game engine metrics are initialized from Prometheus registry, not database.
|
|
71
|
+
// Override in subclass if database-backed metric initialization is needed.
|
|
38
72
|
}
|
|
39
73
|
initializeRegistry() {
|
|
40
74
|
this.metricsRegistry.set('game_engine_commands_total', this.engineCommandsTotal);
|
|
@@ -71,8 +105,14 @@ let PrometheusService = class PrometheusService {
|
|
|
71
105
|
}
|
|
72
106
|
return metric;
|
|
73
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns Prometheus text format metrics from the default prom-client registry.
|
|
110
|
+
* The @willsoto/nestjs-prometheus module also exposes a /metrics HTTP endpoint
|
|
111
|
+
* automatically — this method is for programmatic access via the MetricsPort.
|
|
112
|
+
*/
|
|
74
113
|
async getMetrics() {
|
|
75
|
-
|
|
114
|
+
const { register } = await Promise.resolve().then(() => __importStar(require('prom-client')));
|
|
115
|
+
return register.metrics();
|
|
76
116
|
}
|
|
77
117
|
};
|
|
78
118
|
exports.PrometheusService = PrometheusService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../../src/common/retry/retry-policy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAE5B,OAAO,EAAE,YAAY;IAUpB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../../src/common/retry/retry-policy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAE5B,OAAO,EAAE,YAAY;IAUpB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAgDzD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,cAAc;YAMR,KAAK;CAGpB"}
|
|
@@ -24,7 +24,7 @@ class RetryPolicy {
|
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
26
26
|
catch (error) {
|
|
27
|
-
const err = error;
|
|
27
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
28
28
|
lastError = err;
|
|
29
29
|
if (!this.isRetryable(err)) {
|
|
30
30
|
throw err;
|
|
@@ -39,7 +39,9 @@ class RetryPolicy {
|
|
|
39
39
|
try {
|
|
40
40
|
this.onRetry(attempt, err);
|
|
41
41
|
}
|
|
42
|
-
catch {
|
|
42
|
+
catch (callbackError) {
|
|
43
|
+
this.logger.debug(`onRetry callback threw: ${callbackError instanceof Error ? callbackError.message : String(callbackError)}`);
|
|
44
|
+
}
|
|
43
45
|
}
|
|
44
46
|
await this.sleep(delay);
|
|
45
47
|
}
|
|
@@ -49,8 +51,11 @@ class RetryPolicy {
|
|
|
49
51
|
isRetryable(error) {
|
|
50
52
|
if (!this.retryableErrors || this.retryableErrors.length === 0)
|
|
51
53
|
return true;
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
+
const errorRecord = error;
|
|
55
|
+
const cause = errorRecord.cause;
|
|
56
|
+
const causeCode = typeof cause?.code === 'string' ? cause.code : '';
|
|
57
|
+
const errorCode = typeof errorRecord.code === 'string' ? errorRecord.code : '';
|
|
58
|
+
const text = `${errorCode} ${error.name} ${error.message} ${causeCode}`;
|
|
54
59
|
return this.retryableErrors.some(pattern => text.includes(pattern));
|
|
55
60
|
}
|
|
56
61
|
calculateDelay(attempt) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets-provider.aws.d.ts","sourceRoot":"","sources":["../../../src/common/secrets-provider/secrets-provider.aws.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBACa,kBAAmB,YAAW,eAAe;IAKrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJjE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,cAAc,CAAiB;gBAEa,aAAa,EAAE,aAAa;IAM1E,QAAQ;YAIA,WAAW;
|
|
1
|
+
{"version":3,"file":"secrets-provider.aws.d.ts","sourceRoot":"","sources":["../../../src/common/secrets-provider/secrets-provider.aws.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBACa,kBAAmB,YAAW,eAAe;IAKrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJjE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,cAAc,CAAiB;gBAEa,aAAa,EAAE,aAAa;IAM1E,QAAQ;YAIA,WAAW;IAkCnB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAO/C"}
|
|
@@ -53,7 +53,8 @@ let AwsSecretsProvider = AwsSecretsProvider_1 = class AwsSecretsProvider {
|
|
|
53
53
|
this.logger.log(`Successfully loaded secrets from AWS Secrets Manager.`);
|
|
54
54
|
}
|
|
55
55
|
catch (error) {
|
|
56
|
-
|
|
56
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
57
|
+
this.logger.error(`Failed to retrieve secrets from AWS: ${errorMessage}`);
|
|
57
58
|
throw error;
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -5,22 +5,24 @@ import { setupDocumentation } from '../common/api-docs/setup-documentation';
|
|
|
5
5
|
import { SHUTDOWN_OUT_PORT, } from '../health/application/ports/out/shutdown.out-port';
|
|
6
6
|
import { GameEngineGrpcInAdapter } from '../grpc/game-engine.grpc.in-adapter';
|
|
7
7
|
import { createConnectRouter } from '../grpc/connect-router.middleware';
|
|
8
|
-
import { BadRequestException, RequestMethod, ValidationPipe } from '@nestjs/common';
|
|
8
|
+
import { BadRequestException, RequestMethod, ValidationPipe, } from '@nestjs/common';
|
|
9
9
|
import { ConfigService } from '@nestjs/config';
|
|
10
10
|
import { NestFactory } from '@nestjs/core';
|
|
11
11
|
import * as http2 from 'http2';
|
|
12
|
+
/** Type guard for NestJS dynamic modules with a static `register` method. */
|
|
13
|
+
function hasRegisterMethod(module) {
|
|
14
|
+
return 'register' in module && typeof module.register === 'function';
|
|
15
|
+
}
|
|
12
16
|
/**
|
|
13
17
|
* Creates and bootstraps a game engine NestJS application with
|
|
14
18
|
* standard configuration: CORS, validation pipes, exception filters,
|
|
15
19
|
* Swagger docs, Connect RPC gRPC server, and graceful shutdown.
|
|
16
20
|
*/
|
|
17
21
|
export async function createGameEngineApp(options) {
|
|
18
|
-
const { serviceName, appModule, bootstrapOptions, corsOrigins = false } = options;
|
|
22
|
+
const { serviceName, appModule, bootstrapOptions, corsOrigins = false, additionalRoutes, } = options;
|
|
19
23
|
const logger = new Logger(serviceName);
|
|
20
|
-
const moduleArg = bootstrapOptions
|
|
21
|
-
? appModule.register
|
|
22
|
-
? appModule.register(bootstrapOptions)
|
|
23
|
-
: appModule
|
|
24
|
+
const moduleArg = bootstrapOptions && hasRegisterMethod(appModule)
|
|
25
|
+
? appModule.register(bootstrapOptions)
|
|
24
26
|
: appModule;
|
|
25
27
|
const app = await NestFactory.create(moduleArg, {
|
|
26
28
|
logger: logger,
|
|
@@ -30,42 +32,33 @@ export async function createGameEngineApp(options) {
|
|
|
30
32
|
}
|
|
31
33
|
const configService = app.get(ConfigService);
|
|
32
34
|
const shutdownService = app.get(SHUTDOWN_OUT_PORT);
|
|
33
|
-
|
|
35
|
+
// Fatal error handler uses ShutdownOutPort's guard to prevent duplicate shutdowns.
|
|
36
|
+
// No separate local flag — single source of truth avoids desync.
|
|
34
37
|
const handleFatalError = async (errorType, error) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (isShuttingDown) {
|
|
38
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
39
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
40
|
+
logger.error(`${errorType}:`, { error: errorMessage, stack: errorStack });
|
|
41
|
+
if (shutdownService.isShuttingDown()) {
|
|
40
42
|
logger.warn('Shutdown already in progress, ignoring additional error');
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
|
-
isShuttingDown = true;
|
|
44
45
|
try {
|
|
45
46
|
logger.warn(`Initiating graceful shutdown due to ${errorType}...`);
|
|
46
47
|
await shutdownService.startGracefulShutdown();
|
|
47
48
|
logger.log('Graceful shutdown completed, exiting process');
|
|
48
49
|
}
|
|
49
50
|
catch (shutdownError) {
|
|
50
|
-
|
|
51
|
+
const shutdownMsg = shutdownError instanceof Error ? shutdownError.message : String(shutdownError);
|
|
52
|
+
logger.error(`Error during graceful shutdown: ${shutdownMsg}`);
|
|
51
53
|
}
|
|
52
54
|
finally {
|
|
53
55
|
process.exit(1);
|
|
54
56
|
}
|
|
55
57
|
};
|
|
56
58
|
process.on('uncaughtException', (error) => {
|
|
57
|
-
logger.error('Uncaught Exception:', {
|
|
58
|
-
error: error.message,
|
|
59
|
-
stack: error.stack,
|
|
60
|
-
});
|
|
61
59
|
void handleFatalError('uncaughtException', error);
|
|
62
60
|
});
|
|
63
|
-
process.on('unhandledRejection', (reason
|
|
64
|
-
logger.error('Unhandled Rejection:', {
|
|
65
|
-
reason: reason.message,
|
|
66
|
-
stack: reason.stack,
|
|
67
|
-
promise,
|
|
68
|
-
});
|
|
61
|
+
process.on('unhandledRejection', (reason) => {
|
|
69
62
|
void handleFatalError('unhandledRejection', reason);
|
|
70
63
|
});
|
|
71
64
|
app.setGlobalPrefix('api', {
|
|
@@ -91,11 +84,11 @@ export async function createGameEngineApp(options) {
|
|
|
91
84
|
},
|
|
92
85
|
}));
|
|
93
86
|
app.useGlobalFilters(app.get(ExceptionsFilter));
|
|
94
|
-
const PORT = configService.get('PORT')
|
|
87
|
+
const PORT = configService.get('PORT') ?? 3000;
|
|
95
88
|
await setupDocumentation(app, PORT, serviceName);
|
|
96
89
|
// Setup Connect RPC server
|
|
97
90
|
const gameEngineAdapter = app.get(GameEngineGrpcInAdapter);
|
|
98
|
-
const connectRouter = createConnectRouter(gameEngineAdapter);
|
|
91
|
+
const connectRouter = createConnectRouter(gameEngineAdapter, { additionalRoutes });
|
|
99
92
|
// Mount Connect router on /connect path
|
|
100
93
|
app.use('/connect', connectRouter);
|
|
101
94
|
app.enableShutdownHooks(['SIGTERM', 'SIGINT']);
|
|
@@ -108,14 +101,21 @@ export async function createGameEngineApp(options) {
|
|
|
108
101
|
h2cServer.listen(GRPC_PORT, '0.0.0.0', () => {
|
|
109
102
|
logger.log(`Connect RPC (h2c) is available on: http://localhost:${GRPC_PORT}`);
|
|
110
103
|
});
|
|
111
|
-
//
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
// Register h2c server closure with graceful shutdown service
|
|
105
|
+
shutdownService.registerCleanupCallback('h2c-grpc-server', () => {
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
h2cServer.close(err => {
|
|
108
|
+
if (err) {
|
|
109
|
+
logger.error('Error closing h2c gRPC server:', err);
|
|
110
|
+
reject(err);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
logger.log('h2c gRPC server closed');
|
|
114
|
+
resolve();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
115
117
|
});
|
|
116
|
-
};
|
|
117
|
-
process.on('SIGTERM', closeH2c);
|
|
118
|
-
process.on('SIGINT', closeH2c);
|
|
118
|
+
});
|
|
119
119
|
await app.listen(PORT, '0.0.0.0');
|
|
120
120
|
logger.log(`Application is running on: http://localhost:${PORT}`);
|
|
121
121
|
return app;
|