@ti-engine/core 1.3.3 → 1.3.6
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 +23 -0
- package/README.md +106 -95
- package/bin/localization/labels.json +101 -98
- package/components/exchange/message-dispatcher.js +4 -4
- package/components/exchange/message-tracer.js +4 -3
- package/components/service-caller.js +1 -1
- package/components/service-consumer.js +2 -2
- package/components/service-instance.js +3 -3
- package/components/service-provider.js +2 -2
- package/integrations/redis-integration.js +11 -10
- package/package.json +3 -4
- package/utils/exceptions.js +117 -22
- package/utils/logger.js +1 -1
- package/utils/tools.js +142 -96
|
@@ -1,99 +1,102 @@
|
|
|
1
|
-
{
|
|
2
|
-
"system": {
|
|
3
|
-
"exceptions": {
|
|
4
|
-
"0": {
|
|
5
|
-
"en": "Unidentified error encountered or unrecognized exception code provided."
|
|
6
|
-
},
|
|
7
|
-
"1000": {
|
|
8
|
-
"en": "Error thrown by internal JS source."
|
|
9
|
-
},
|
|
10
|
-
"1001": {
|
|
11
|
-
"en": "Attempt to construct an abstract class detected."
|
|
12
|
-
},
|
|
13
|
-
"1002": {
|
|
14
|
-
"en": "Attempt to call an abstract method detected."
|
|
15
|
-
},
|
|
16
|
-
"1003": {
|
|
17
|
-
"en": "Invalid or no service domain name provided at microservice startup."
|
|
18
|
-
},
|
|
19
|
-
"1004": {
|
|
20
|
-
"en": "The system cache required for proper engine operation is unavailable."
|
|
21
|
-
},
|
|
22
|
-
"1005": {
|
|
23
|
-
"en": "The provided service handler is not a proper function."
|
|
24
|
-
},
|
|
25
|
-
"1006": {
|
|
26
|
-
"en": "The requested feature is not supported by current configuration or version."
|
|
27
|
-
},
|
|
28
|
-
"
|
|
29
|
-
"en": "
|
|
30
|
-
},
|
|
31
|
-
"
|
|
32
|
-
"en": "Invalid
|
|
33
|
-
},
|
|
34
|
-
"
|
|
35
|
-
"en": "
|
|
36
|
-
},
|
|
37
|
-
"
|
|
38
|
-
"en": "
|
|
39
|
-
},
|
|
40
|
-
"
|
|
41
|
-
"en": "
|
|
42
|
-
},
|
|
43
|
-
"
|
|
44
|
-
"en": "
|
|
45
|
-
},
|
|
46
|
-
"
|
|
47
|
-
"en": "The
|
|
48
|
-
},
|
|
49
|
-
"
|
|
50
|
-
"en": "The
|
|
51
|
-
},
|
|
52
|
-
"
|
|
53
|
-
"en": "The specified service is not found in the service
|
|
54
|
-
},
|
|
55
|
-
"
|
|
56
|
-
"en": "
|
|
57
|
-
},
|
|
58
|
-
"
|
|
59
|
-
"en": "
|
|
60
|
-
},
|
|
61
|
-
"
|
|
62
|
-
"en": "The message
|
|
63
|
-
},
|
|
64
|
-
"
|
|
65
|
-
"en": "
|
|
66
|
-
},
|
|
67
|
-
"
|
|
68
|
-
"en": "
|
|
69
|
-
},
|
|
70
|
-
"
|
|
71
|
-
"en": "The request
|
|
72
|
-
},
|
|
73
|
-
"
|
|
74
|
-
"en": "The request
|
|
75
|
-
},
|
|
76
|
-
"
|
|
77
|
-
"en": "The request
|
|
78
|
-
},
|
|
79
|
-
"
|
|
80
|
-
"en": "The request
|
|
81
|
-
},
|
|
82
|
-
"
|
|
83
|
-
"en": "The request
|
|
84
|
-
},
|
|
85
|
-
"
|
|
86
|
-
"en": "The request
|
|
87
|
-
},
|
|
88
|
-
"
|
|
89
|
-
"en": "The request
|
|
90
|
-
},
|
|
91
|
-
"
|
|
92
|
-
"en": "The request content
|
|
93
|
-
},
|
|
94
|
-
"
|
|
95
|
-
"en": "The request content
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
1
|
+
{
|
|
2
|
+
"system": {
|
|
3
|
+
"exceptions": {
|
|
4
|
+
"0": {
|
|
5
|
+
"en": "Unidentified error encountered or unrecognized exception code provided."
|
|
6
|
+
},
|
|
7
|
+
"1000": {
|
|
8
|
+
"en": "Error thrown by internal JS source."
|
|
9
|
+
},
|
|
10
|
+
"1001": {
|
|
11
|
+
"en": "Attempt to construct an abstract class detected."
|
|
12
|
+
},
|
|
13
|
+
"1002": {
|
|
14
|
+
"en": "Attempt to call an abstract method detected."
|
|
15
|
+
},
|
|
16
|
+
"1003": {
|
|
17
|
+
"en": "Invalid or no service domain name provided at microservice startup."
|
|
18
|
+
},
|
|
19
|
+
"1004": {
|
|
20
|
+
"en": "The system cache required for proper engine operation is unavailable."
|
|
21
|
+
},
|
|
22
|
+
"1005": {
|
|
23
|
+
"en": "The provided service handler is not a proper function."
|
|
24
|
+
},
|
|
25
|
+
"1006": {
|
|
26
|
+
"en": "The requested feature is not supported by current configuration or version."
|
|
27
|
+
},
|
|
28
|
+
"1007": {
|
|
29
|
+
"en": "The provided argument is not of the expected type."
|
|
30
|
+
},
|
|
31
|
+
"2000": {
|
|
32
|
+
"en": "Invalid authorization token provided."
|
|
33
|
+
},
|
|
34
|
+
"2001": {
|
|
35
|
+
"en": "Invalid or expired session encountered."
|
|
36
|
+
},
|
|
37
|
+
"2002": {
|
|
38
|
+
"en": "Attempt for unauthorized access detected."
|
|
39
|
+
},
|
|
40
|
+
"2003": {
|
|
41
|
+
"en": "The system detected tampering with the message received via message exchange."
|
|
42
|
+
},
|
|
43
|
+
"3000": {
|
|
44
|
+
"en": "General error during cross-application communication."
|
|
45
|
+
},
|
|
46
|
+
"3001": {
|
|
47
|
+
"en": "The message sender instance is currently unavailable."
|
|
48
|
+
},
|
|
49
|
+
"3002": {
|
|
50
|
+
"en": "The execution of a service could not complete within the allowed timeout."
|
|
51
|
+
},
|
|
52
|
+
"3003": {
|
|
53
|
+
"en": "The specified service is not found in the service registry."
|
|
54
|
+
},
|
|
55
|
+
"3004": {
|
|
56
|
+
"en": "The specified service is not found in the service definition interface."
|
|
57
|
+
},
|
|
58
|
+
"3005": {
|
|
59
|
+
"en": "No handler found in the interface for the specified service or service version."
|
|
60
|
+
},
|
|
61
|
+
"3006": {
|
|
62
|
+
"en": "The message receiver instance is currently unavailable."
|
|
63
|
+
},
|
|
64
|
+
"3007": {
|
|
65
|
+
"en": "The message exchange is irrevocably broken and cannot be used any longer."
|
|
66
|
+
},
|
|
67
|
+
"3010": {
|
|
68
|
+
"en": "Connection retry attempts exceeded the configured limit."
|
|
69
|
+
},
|
|
70
|
+
"4000": {
|
|
71
|
+
"en": "The request method is not recognized or not supported."
|
|
72
|
+
},
|
|
73
|
+
"4001": {
|
|
74
|
+
"en": "The request URI is not recognized or not supported."
|
|
75
|
+
},
|
|
76
|
+
"4002": {
|
|
77
|
+
"en": "The request body is not recognized or not supported."
|
|
78
|
+
},
|
|
79
|
+
"4003": {
|
|
80
|
+
"en": "The request query is not recognized or not supported."
|
|
81
|
+
},
|
|
82
|
+
"4004": {
|
|
83
|
+
"en": "The request headers are not recognized or not supported."
|
|
84
|
+
},
|
|
85
|
+
"4005": {
|
|
86
|
+
"en": "The request parameters are not recognized or not supported."
|
|
87
|
+
},
|
|
88
|
+
"4006": {
|
|
89
|
+
"en": "The request format is not recognized or not supported."
|
|
90
|
+
},
|
|
91
|
+
"4007": {
|
|
92
|
+
"en": "The request content type is not recognized or not supported."
|
|
93
|
+
},
|
|
94
|
+
"4008": {
|
|
95
|
+
"en": "The request content length is not recognized or not supported."
|
|
96
|
+
},
|
|
97
|
+
"4009": {
|
|
98
|
+
"en": "The request content encoding is not recognized or not supported."
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
99
102
|
}
|
|
@@ -95,8 +95,8 @@ class MessageDispatcher {
|
|
|
95
95
|
retry.onFailedAttempt( ( error ) => {
|
|
96
96
|
logger.log( `Failed to send message request with chain ID: ${ message.chainID }`, logger.logSeverity.WARNING, error );
|
|
97
97
|
} );
|
|
98
|
-
retry.onRetry( ( attempt ) => {
|
|
99
|
-
logger.log( `Retrying to send message response with chain ID: ${ message.chainID }. This is attempt ${ attempt }...`, logger.logSeverity.NOTICE );
|
|
98
|
+
retry.onRetry( ( attempt, error ) => {
|
|
99
|
+
logger.log( `Retrying to send message response with chain ID: ${ message.chainID }. This is attempt ${ attempt }...`, logger.logSeverity.NOTICE, ( error ) ? { error: tools.errorToJSON( error ) } : undefined );
|
|
100
100
|
} );
|
|
101
101
|
|
|
102
102
|
messageTracer.instance.recordTraceEntry( message, messageTracer.messageType.MESSAGE_REQUEST, messageTracer.dispatchEvent.SENT, messageTracer.messageState.PENDING );
|
|
@@ -125,8 +125,8 @@ class MessageDispatcher {
|
|
|
125
125
|
retry.onFailedAttempt( ( error ) => {
|
|
126
126
|
logger.log( `Failed to send message response with chain ID: ${ message.chainID }`, logger.logSeverity.WARNING, error );
|
|
127
127
|
} );
|
|
128
|
-
retry.onRetry( ( attempt ) => {
|
|
129
|
-
logger.log( `Retrying to send message response with chain ID: ${ message.chainID }. This is attempt ${ attempt }...`, logger.logSeverity.NOTICE );
|
|
128
|
+
retry.onRetry( ( attempt, error ) => {
|
|
129
|
+
logger.log( `Retrying to send message response with chain ID: ${ message.chainID }. This is attempt ${ attempt }...`, logger.logSeverity.NOTICE, ( error ) ? { error: tools.errorToJSON( error ) } : undefined );
|
|
130
130
|
} );
|
|
131
131
|
|
|
132
132
|
messageTracer.instance.recordTraceEntry( message, messageTracer.messageType.MESSAGE_RESPONSE, messageTracer.dispatchEvent.SENT, messageTracer.messageState.PROCESSED );
|
|
@@ -30,6 +30,7 @@ const cache = require( "#cache" );
|
|
|
30
30
|
const traceRoot = {
|
|
31
31
|
trace: []
|
|
32
32
|
};
|
|
33
|
+
const UNKNOWN_TOKEN = "UNKNOWN";
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Enum for listing message types.
|
|
@@ -155,12 +156,12 @@ class MessageTracer {
|
|
|
155
156
|
/** @type TiTraceEntry */
|
|
156
157
|
let traceEntry = {
|
|
157
158
|
chainID: message.chainID,
|
|
158
|
-
dispatchEvent:
|
|
159
|
+
dispatchEvent: dispatchEventEnum.name( dispatchEvent, UNKNOWN_TOKEN ),
|
|
159
160
|
fromAddress: ( messageType === messageTypeEnum.MESSAGE_REQUEST ) ? source : destination,
|
|
160
161
|
messageID: message.messageID,
|
|
161
162
|
messageSnapshot: messageSnapshot,
|
|
162
|
-
messageState:
|
|
163
|
-
messageType:
|
|
163
|
+
messageState: messageStateEnum.name( messageState, UNKNOWN_TOKEN ),
|
|
164
|
+
messageType: messageTypeEnum.name( messageType, UNKNOWN_TOKEN ),
|
|
164
165
|
toAddress: ( messageType === messageTypeEnum.MESSAGE_REQUEST ) ? destination : source,
|
|
165
166
|
traceTimestamp: currentDate.getTime(),
|
|
166
167
|
traceID: tools.getUUID()
|
|
@@ -187,7 +187,7 @@ class ServiceCallProcessor {
|
|
|
187
187
|
} ).catch( ( error ) => {
|
|
188
188
|
clearTimeout( this.#timeoutHandle );
|
|
189
189
|
this.#isProcessed = true;
|
|
190
|
-
logger.log( `Error during service call execution!`, logger.logSeverity.
|
|
190
|
+
logger.log( `Error during service call execution!`, logger.logSeverity.DEBUG, error );
|
|
191
191
|
return {
|
|
192
192
|
isSuccessful: false,
|
|
193
193
|
exception: exceptions.raise( error ),
|
|
@@ -32,9 +32,9 @@ class ServiceConsumer extends ServiceInstance {
|
|
|
32
32
|
/**
|
|
33
33
|
* @constructor
|
|
34
34
|
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
35
|
-
* @param {
|
|
35
|
+
* @param {ServiceConfiguration} [serviceConfig] The JSON configuration for this service.
|
|
36
36
|
*/
|
|
37
|
-
constructor( serviceDomainName, serviceConfig
|
|
37
|
+
constructor( serviceDomainName, serviceConfig ) {
|
|
38
38
|
super( serviceDomainName, serviceConfig );
|
|
39
39
|
|
|
40
40
|
// make sure this abstract class cannot be instantiated:
|
|
@@ -17,7 +17,7 @@ const messageDispatcher = require( "#message-dispatcher" );
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @typedef {Object} ServiceConfiguration
|
|
20
|
-
* @property {ServiceDefinition[]} services A list of service definitions to be registered with the {@link ServiceProvider}.
|
|
20
|
+
* @property {ServiceDefinition[]} [services] A list of service definitions to be registered with the {@link ServiceProvider}.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -42,9 +42,9 @@ class ServiceInstance {
|
|
|
42
42
|
/**
|
|
43
43
|
* @constructor
|
|
44
44
|
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
45
|
-
* @param {
|
|
45
|
+
* @param {ServiceConfiguration} [serviceConfig={ services: [] }] The JSON configuration for this service.
|
|
46
46
|
*/
|
|
47
|
-
constructor( serviceDomainName, serviceConfig = {} ) {
|
|
47
|
+
constructor( serviceDomainName, serviceConfig = { services: [] } ) {
|
|
48
48
|
// Ensure this abstract class cannot be instantiated:
|
|
49
49
|
if ( new.target === ServiceInstance ) {
|
|
50
50
|
throw exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_CLASS_INIT, { name: this.constructor.name } );
|
|
@@ -37,9 +37,9 @@ class ServiceProvider extends ServiceConsumer {
|
|
|
37
37
|
/**
|
|
38
38
|
* @constructor
|
|
39
39
|
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
40
|
-
* @param {
|
|
40
|
+
* @param {ServiceConfiguration} [serviceConfig] The JSON configuration for this service.
|
|
41
41
|
*/
|
|
42
|
-
constructor( serviceDomainName, serviceConfig
|
|
42
|
+
constructor( serviceDomainName, serviceConfig ) {
|
|
43
43
|
super( serviceDomainName, serviceConfig );
|
|
44
44
|
|
|
45
45
|
// make sure this abstract class cannot be instantiated:
|
|
@@ -118,7 +118,7 @@ class RedisClient {
|
|
|
118
118
|
/* Public interface */
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
|
-
* Used to return the Redis client identifier.
|
|
121
|
+
* Used to return the Redis client identifier assigned internally.
|
|
122
122
|
*
|
|
123
123
|
* @property
|
|
124
124
|
* @returns {string}
|
|
@@ -129,7 +129,7 @@ class RedisClient {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
|
-
* Used to return the
|
|
132
|
+
* Used to return the client ID assigned by the Redis server.
|
|
133
133
|
*
|
|
134
134
|
* @property
|
|
135
135
|
* @returns {number}
|
|
@@ -195,9 +195,9 @@ class RedisClient {
|
|
|
195
195
|
// Fetch the server information and store it:
|
|
196
196
|
return this.#fetchServerInfo();
|
|
197
197
|
} ).then( () => {
|
|
198
|
-
return this.#
|
|
198
|
+
return this.#getClientID();
|
|
199
199
|
} ).then( ( clientID ) => {
|
|
200
|
-
// Store the
|
|
200
|
+
// Store the connection ID:
|
|
201
201
|
this.#redisClientID = clientID;
|
|
202
202
|
resolve();
|
|
203
203
|
} ).catch( ( error ) => {
|
|
@@ -476,10 +476,12 @@ class RedisClient {
|
|
|
476
476
|
|
|
477
477
|
this.#redisConnection.once( "ready", () => {
|
|
478
478
|
this.#clientStatus = clientStatusEnum.CONNECTED;
|
|
479
|
+
logger.log( `Connection to Redis server '${ this.#redisConnection.options.host }:${ this.#redisConnection.options.port }' established by client '${ this.identifier }' and is ready to be used.`, logger.logSeverity.INFO );
|
|
479
480
|
this.#notifyConnectionObservers();
|
|
480
481
|
|
|
481
482
|
this.#redisConnection.on( "ready", () => {
|
|
482
483
|
this.#clientStatus = clientStatusEnum.CONNECTED;
|
|
484
|
+
logger.log( `Connection to Redis server '${ this.#redisConnection.options.host }:${ this.#redisConnection.options.port }' reestablished by client '${ this.identifier }' and is ready to be used.`, logger.logSeverity.INFO );
|
|
483
485
|
this.#notifyConnectionObservers();
|
|
484
486
|
} );
|
|
485
487
|
|
|
@@ -515,14 +517,13 @@ class RedisClient {
|
|
|
515
517
|
*/
|
|
516
518
|
#notifyConnectionObservers() {
|
|
517
519
|
// Notify all connection observers about the event:
|
|
518
|
-
_.forEach( this.#connectionObservers, (
|
|
520
|
+
_.forEach( this.#connectionObservers, ( connectionObserver ) => {
|
|
519
521
|
if ( this.#clientStatus === clientStatusEnum.CONNECTED ) {
|
|
520
|
-
|
|
521
|
-
connectionObservers.onConnectionRecovered( this.#clientIdentifier );
|
|
522
|
+
connectionObserver.onConnectionRecovered( this.#clientIdentifier );
|
|
522
523
|
} else if ( this.#clientStatus === clientStatusEnum.DISRUPTED ) {
|
|
523
|
-
|
|
524
|
+
connectionObserver.onConnectionDisrupted( this.#clientIdentifier );
|
|
524
525
|
} else if ( this.#clientStatus === clientStatusEnum.DISCONNECTED ) {
|
|
525
|
-
|
|
526
|
+
connectionObserver.onConnectionLost( this.#clientIdentifier );
|
|
526
527
|
}
|
|
527
528
|
} );
|
|
528
529
|
}
|
|
@@ -574,7 +575,7 @@ class RedisClient {
|
|
|
574
575
|
* @returns {Promise<number>}
|
|
575
576
|
* @private
|
|
576
577
|
*/
|
|
577
|
-
#
|
|
578
|
+
#getClientID() {
|
|
578
579
|
let commandArguments = [ "client", "id" ];
|
|
579
580
|
return this.callCommand( commandArguments ).then( ( clientID ) => Number( clientID ) );
|
|
580
581
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "The ti-engine is an open source, free to use—both for personal and commercial projects—framework for the creation of microservice-based solutions using node.js.",
|
|
5
5
|
"author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -47,8 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"blake2": "^5.0.0",
|
|
50
|
-
"@dotenvx/dotenvx": "^1.49.
|
|
51
|
-
"fs-extra": "^11.3.1",
|
|
50
|
+
"@dotenvx/dotenvx": "^1.49.1",
|
|
52
51
|
"lodash": "^4.17.21",
|
|
53
52
|
"node-schedule": "^2.1.1",
|
|
54
53
|
"ioredis": "^5.7.0"
|
|
@@ -62,6 +61,6 @@
|
|
|
62
61
|
"url": "git+https://github.com/Belleal/ti-engine.git"
|
|
63
62
|
},
|
|
64
63
|
"engines": {
|
|
65
|
-
"node": ">=
|
|
64
|
+
"node": ">=18.0.0"
|
|
66
65
|
}
|
|
67
66
|
}
|
package/utils/exceptions.js
CHANGED
|
@@ -25,6 +25,7 @@ const exceptionCodeEnum = tools.enum( {
|
|
|
25
25
|
E_GEN_SYSTEM_CACHE_UNAVAILABLE: [ 1004, "system cache unavailable", "The system cache required for proper engine operation is unavailable." ],
|
|
26
26
|
E_GEN_BAD_SERVICE_HANDLER: [ 1005, "bad service handler", "The provided service handler is not a proper function." ],
|
|
27
27
|
E_GEN_FEATURE_UNSUPPORTED: [ 1006, "feature unsupported", "The requested feature is not supported by current configuration or version." ],
|
|
28
|
+
E_GEN_INVALID_ARGUMENT_TYPE: [ 1007, "invalid argument type", "The provided argument is not of the expected type." ],
|
|
28
29
|
/** Security & Administration exceptions - codes under 2xxx */
|
|
29
30
|
E_SEC_INVALID_AUTH_TOKEN: [ 2000, "invalid auth token", "Invalid authorization token provided." ],
|
|
30
31
|
E_SEC_INVALID_EXPIRED_SESSION: [ 2001, "invalid or expired session", "Invalid or expired session encountered." ],
|
|
@@ -53,11 +54,89 @@ const exceptionCodeEnum = tools.enum( {
|
|
|
53
54
|
E_WEB_INVALID_REQUEST_CONTENT_ENCODING: [ 4009, "invalid request content encoding", "The request content encoding is not recognized or not supported." ]
|
|
54
55
|
} );
|
|
55
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Enum for listing all HTTP codes.
|
|
59
|
+
*
|
|
60
|
+
* @readonly
|
|
61
|
+
* @enum {number}
|
|
62
|
+
*/
|
|
63
|
+
const httpCodeEnum = tools.enum( {
|
|
64
|
+
/** 1xx informational response */
|
|
65
|
+
C_100: [ 100, "Continue", "The server has received the request headers and the client should proceed to send the request body." ],
|
|
66
|
+
C_101: [ 101, "Switching Protocols", "The requester has asked the server to switch protocols and the server has agreed to do so." ],
|
|
67
|
+
C_102: [ 102, "Processing", "This code indicates that the server has received and is processing the request, but no response is available yet." ],
|
|
68
|
+
C_103: [ 103, "Early Hints", "Used to return some response headers before final HTTP message." ],
|
|
69
|
+
/** 2xx success */
|
|
70
|
+
C_200: [ 200, "OK", "Standard response for successful HTTP requests." ],
|
|
71
|
+
C_201: [ 201, "Created", "The request has been fulfilled, resulting in the creation of a new resource." ],
|
|
72
|
+
C_202: [ 202, "Accepted", "The request has been accepted for processing, but the processing has not been completed." ],
|
|
73
|
+
C_203: [ 203, "Non-Authoritative Information", "The server is a transforming proxy that received a 200 OK from its origin, but is returning a modified version of the origin's response." ],
|
|
74
|
+
C_204: [ 204, "No Content", "The server successfully processed the request, and is not returning any content." ],
|
|
75
|
+
C_205: [ 205, "Reset Content", "The server successfully processed the request, asks that the requester reset its document view, and is not returning any content." ],
|
|
76
|
+
C_206: [ 206, "Partial Content", "The server is delivering only part of the resource (byte serving) due to a range header sent by the client." ],
|
|
77
|
+
C_207: [ 207, "Multi-Status", "The message body that follows is by default an XML message and can contain a number of separate response codes, depending on how many sub-requests were made." ],
|
|
78
|
+
C_208: [ 208, "Already Reported", "The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response, and are not being included again." ],
|
|
79
|
+
C_226: [ 226, "IM Used", "The server has fulfilled a request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance." ],
|
|
80
|
+
/** 3xx redirection */
|
|
81
|
+
C_300: [ 300, "Multiple Choices", "Indicates multiple options for the resource from which the client may choose." ],
|
|
82
|
+
C_301: [ 301, "Moved Permanently", "This and all future requests should be directed to the given URI." ],
|
|
83
|
+
C_302: [ 302, "Found", "Tells the client to look at (browse to) another URL." ],
|
|
84
|
+
C_303: [ 303, "See Other", "The response to the request can be found under another URI using the GET method." ],
|
|
85
|
+
C_304: [ 304, "Not Modified", "Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match." ],
|
|
86
|
+
C_307: [ 307, "Temporary Redirect", "In this case, the request should be repeated with another URI; however, future requests should still use the original URI." ],
|
|
87
|
+
C_308: [ 308, "Permanent Redirect", "This and all future requests should be directed to the given URI. 308 parallels the behavior of 301, but does not allow the HTTP method to change." ],
|
|
88
|
+
/** 4xx client errors */
|
|
89
|
+
C_400: [ 400, "Bad Request", "The server cannot or will not process the request due to an apparent client error." ],
|
|
90
|
+
C_401: [ 401, "Unauthorized", "Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided." ],
|
|
91
|
+
C_403: [ 403, "Forbidden", "The request contained valid data and was understood by the server, but the server is refusing action. This may be due to the user not having the necessary permissions for a resource or needing an account of some sort, or attempting a prohibited action." ],
|
|
92
|
+
C_404: [ 404, "Not Found", "The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible." ],
|
|
93
|
+
C_405: [ 405, "Method Not Allowed", "A request method is not supported for the requested resource; for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource." ],
|
|
94
|
+
C_406: [ 406, "Not Acceptable", "The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request." ],
|
|
95
|
+
C_407: [ 407, "Proxy Authentication Required", "The client must first authenticate itself with the proxy." ],
|
|
96
|
+
C_408: [ 408, "Request Timeout", "The server timed out waiting for the request." ],
|
|
97
|
+
C_409: [ 409, "Conflict", "Indicates that the request could not be processed because of conflict in the current state of the resource, such as an edit conflict between multiple simultaneous updates." ],
|
|
98
|
+
C_410: [ 410, "Gone", "Indicates that the resource requested was previously in use but is no longer available and will not be available again." ],
|
|
99
|
+
C_411: [ 411, "Length Required", "The request did not specify the length of its content, which is required by the requested resource." ],
|
|
100
|
+
C_412: [ 412, "Precondition Failed", "The server does not meet one of the preconditions that the requester put on the request header fields." ],
|
|
101
|
+
C_413: [ 413, "Payload Too Large", "The request is larger than the server is willing or able to process." ],
|
|
102
|
+
C_414: [ 414, "URI Too Long", "The URI provided was too long for the server to process." ],
|
|
103
|
+
C_415: [ 415, "Unsupported Media Type", "The request entity has a media type which the server or resource does not support." ],
|
|
104
|
+
C_416: [ 416, "Range Not Satisfiable", "The client has asked for a portion of the file (byte serving), but the server cannot supply that portion." ],
|
|
105
|
+
C_417: [ 417, "Expectation Failed", "The server cannot meet the requirements of the Expect request-header field." ],
|
|
106
|
+
C_421: [ 421, "Misdirected Request", "The request was directed at a server that is not able to produce a response (for example because of connection reuse)." ],
|
|
107
|
+
C_422: [ 422, "Unprocessable Content", "The request was well-formed (i.e., syntactically correct) but could not be processed." ],
|
|
108
|
+
C_423: [ 423, "Locked", "The resource that is being accessed is locked." ],
|
|
109
|
+
C_424: [ 424, "Failed Dependency", "The request failed because it depended on another request and that request failed." ],
|
|
110
|
+
C_425: [ 425, "Too Early", "Indicates that the server is unwilling to risk processing a request that might be replayed." ],
|
|
111
|
+
C_426: [ 426, "Upgrade Required", "The client should switch to a different protocol such as TLS/1.3, given in the Upgrade header field." ],
|
|
112
|
+
C_428: [ 428, "Precondition Required", "The origin server requires the request to be conditional." ],
|
|
113
|
+
C_429: [ 429, "Too Many Requests", "The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes." ],
|
|
114
|
+
C_431: [ 431, "Request Header Fields Too Large", "The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large." ],
|
|
115
|
+
C_451: [ 451, "Unavailable For Legal Reasons", "A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource." ],
|
|
116
|
+
/** 5xx server errors */
|
|
117
|
+
C_500: [ 500, "Internal Server Error", "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable." ],
|
|
118
|
+
C_501: [ 501, "Not Implemented", "The server either does not recognize the request method, or it lacks the ability to fulfil the request." ],
|
|
119
|
+
C_502: [ 502, "Bad Gateway", "The server was acting as a gateway or proxy and received an invalid response from the upstream server." ],
|
|
120
|
+
C_503: [ 503, "Service Unavailable", "The server cannot handle the request (because it is overloaded or down for maintenance)." ],
|
|
121
|
+
C_504: [ 504, "Gateway Timeout", "The server was acting as a gateway or proxy and did not receive a timely response from the upstream server." ],
|
|
122
|
+
C_505: [ 505, "HTTP Version Not Supported", "The server does not support the HTTP version used in the request." ],
|
|
123
|
+
C_506: [ 506, "Variant Also Negotiates", "Transparent content negotiation for the request results in a circular reference." ],
|
|
124
|
+
C_507: [ 507, "Insufficient Storage", "The server is unable to store the representation needed to complete the request." ],
|
|
125
|
+
C_508: [ 508, "Loop Detected", "The server detected an infinite loop while processing the request." ],
|
|
126
|
+
C_510: [ 510, "Not Extended", "Further extensions to the request are required for the server to fulfil it." ],
|
|
127
|
+
C_511: [ 511, "Network Authentication Required", "The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control access to the network." ]
|
|
128
|
+
} );
|
|
129
|
+
|
|
56
130
|
/**
|
|
57
131
|
* @typedef {number} TiExceptionCode
|
|
58
132
|
*/
|
|
59
133
|
module.exports.exceptionCode = exceptionCodeEnum;
|
|
60
134
|
|
|
135
|
+
/**
|
|
136
|
+
* @typedef {number} TiHttpCode
|
|
137
|
+
*/
|
|
138
|
+
module.exports.httpCode = httpCodeEnum;
|
|
139
|
+
|
|
61
140
|
const labelPath = "system.exceptions.";
|
|
62
141
|
|
|
63
142
|
/**
|
|
@@ -68,28 +147,27 @@ const labelPath = "system.exceptions.";
|
|
|
68
147
|
*/
|
|
69
148
|
class Exception {
|
|
70
149
|
|
|
71
|
-
#id
|
|
72
|
-
#code
|
|
73
|
-
#httpCode
|
|
74
|
-
#label
|
|
75
|
-
#description
|
|
76
|
-
#data
|
|
150
|
+
#id;
|
|
151
|
+
#code;
|
|
152
|
+
#httpCode;
|
|
153
|
+
#label;
|
|
154
|
+
#description;
|
|
155
|
+
#data;
|
|
77
156
|
|
|
78
157
|
/**
|
|
79
158
|
* @constructor
|
|
80
159
|
* @param {string} id The unique ID to be assigned to this exception.
|
|
81
160
|
* @param {TiExceptionCode} exceptionCode An unique exception identifier. If this is not recognized, the default error code will be used instead.
|
|
82
|
-
* @param {Object} [data] Any additional data to insert into the exception.
|
|
83
|
-
* @param {string} [description] Description of the exception.
|
|
161
|
+
* @param {Object} [data={}] Any additional data to insert into the exception.
|
|
162
|
+
* @param {string} [description=undefined] Description of the exception.
|
|
84
163
|
*/
|
|
85
164
|
constructor( id, exceptionCode, data, description ) {
|
|
86
|
-
exceptionCode =
|
|
165
|
+
exceptionCode = exceptionCodeEnum.contains( exceptionCode ) ? exceptionCode : exceptionCodeEnum.E_UNKNOWN_ERROR;
|
|
87
166
|
|
|
88
167
|
this.#id = id;
|
|
89
168
|
this.#code = exceptionCode;
|
|
90
|
-
this.#httpCode = undefined;
|
|
91
169
|
this.#label = labelPath + exceptionCode;
|
|
92
|
-
this.#description = description || exceptionCodeEnum.
|
|
170
|
+
this.#description = description || exceptionCodeEnum.description( exceptionCode );
|
|
93
171
|
this.#data = data || {};
|
|
94
172
|
}
|
|
95
173
|
|
|
@@ -121,7 +199,7 @@ class Exception {
|
|
|
121
199
|
* HTTP error code if relevant.
|
|
122
200
|
*
|
|
123
201
|
* @property
|
|
124
|
-
* @returns {
|
|
202
|
+
* @returns {TiHttpCode}
|
|
125
203
|
* @public
|
|
126
204
|
*/
|
|
127
205
|
get httpCode() {
|
|
@@ -132,11 +210,15 @@ class Exception {
|
|
|
132
210
|
* HTTP error code if relevant.
|
|
133
211
|
*
|
|
134
212
|
* @property
|
|
135
|
-
* @param {
|
|
213
|
+
* @param {TiHttpCode} httpCode
|
|
136
214
|
* @public
|
|
137
215
|
*/
|
|
138
216
|
set httpCode( httpCode ) {
|
|
139
|
-
|
|
217
|
+
if ( httpCodeEnum.contains( httpCode ) ) {
|
|
218
|
+
this.#httpCode = httpCode;
|
|
219
|
+
} else {
|
|
220
|
+
this.#httpCode = undefined;
|
|
221
|
+
}
|
|
140
222
|
}
|
|
141
223
|
|
|
142
224
|
/**
|
|
@@ -192,14 +274,19 @@ class Exception {
|
|
|
192
274
|
* @public
|
|
193
275
|
*/
|
|
194
276
|
asJSON( includeData = true ) {
|
|
195
|
-
|
|
277
|
+
let json = {
|
|
196
278
|
id: this.id,
|
|
197
279
|
code: this.code,
|
|
198
|
-
httpCode: this.httpCode,
|
|
199
280
|
label: this.label,
|
|
200
|
-
description: this.description
|
|
201
|
-
data: ( includeData === true ) ? this.data : undefined
|
|
281
|
+
description: this.description
|
|
202
282
|
};
|
|
283
|
+
if ( this.#httpCode !== undefined ) {
|
|
284
|
+
json.httpCode = this.#httpCode;
|
|
285
|
+
}
|
|
286
|
+
if ( includeData === true ) {
|
|
287
|
+
json.data = this.#data;
|
|
288
|
+
}
|
|
289
|
+
return json;
|
|
203
290
|
}
|
|
204
291
|
}
|
|
205
292
|
|
|
@@ -218,17 +305,25 @@ module.exports.raise = ( source, data, exceptionID ) => {
|
|
|
218
305
|
let exception;
|
|
219
306
|
|
|
220
307
|
if ( source instanceof Error ) {
|
|
221
|
-
exception = new Exception( exceptionID || tools.getUUID(),
|
|
308
|
+
exception = new Exception( exceptionID || tools.getUUID(), exceptionCodeEnum.E_GEN_JS_INTERNAL_ERROR, tools.errorToJSON( source ) );
|
|
222
309
|
} else if ( source instanceof Exception ) {
|
|
223
310
|
exception = source;
|
|
224
311
|
} else if ( _.isString( source ) ) {
|
|
225
|
-
exception = new Exception( exceptionID || tools.getUUID(),
|
|
312
|
+
exception = new Exception( exceptionID || tools.getUUID(), exceptionCodeEnum.E_GEN_JS_INTERNAL_ERROR, {
|
|
226
313
|
message: source
|
|
227
314
|
} );
|
|
228
315
|
} else if ( _.isObjectLike( source ) ) {
|
|
229
|
-
exception = new Exception(
|
|
316
|
+
exception = new Exception(
|
|
317
|
+
exceptionID || ( source.id || tools.getUUID() ),
|
|
318
|
+
source.code || exceptionCodeEnum.E_GEN_JS_INTERNAL_ERROR,
|
|
319
|
+
source.data,
|
|
320
|
+
source.description
|
|
321
|
+
);
|
|
322
|
+
if ( httpCodeEnum.contains( source.httpCode ) ) {
|
|
323
|
+
exception.httpCode = source.httpCode;
|
|
324
|
+
}
|
|
230
325
|
} else {
|
|
231
|
-
exception = new Exception( exceptionID || tools.getUUID(), ( exceptionCodeEnum.
|
|
326
|
+
exception = new Exception( exceptionID || tools.getUUID(), ( exceptionCodeEnum.contains( source ) ) ? source : exceptionCodeEnum.E_UNKNOWN_ERROR );
|
|
232
327
|
}
|
|
233
328
|
|
|
234
329
|
// Merge the default exception data with the additional one if it's provided:
|
package/utils/logger.js
CHANGED
|
@@ -42,7 +42,7 @@ module.exports.logSeverity = logSeverityEnum;
|
|
|
42
42
|
* @returns {string}
|
|
43
43
|
*/
|
|
44
44
|
module.exports.getSeverityName = ( severity ) => {
|
|
45
|
-
return
|
|
45
|
+
return logSeverityEnum.name( severity, "unknown" );
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|