@axinom/mosaic-service-common 0.33.0 → 0.34.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/errors/mosaic-errors.d.ts +8 -0
- package/dist/common/errors/mosaic-errors.d.ts.map +1 -1
- package/dist/common/errors/mosaic-errors.js +8 -0
- package/dist/common/errors/mosaic-errors.js.map +1 -1
- package/dist/common/helpers/object-helpers.d.ts +8 -0
- package/dist/common/helpers/object-helpers.d.ts.map +1 -1
- package/dist/common/helpers/object-helpers.js +19 -1
- package/dist/common/helpers/object-helpers.js.map +1 -1
- package/dist/common/logging/generate-log.d.ts.map +1 -1
- package/dist/common/logging/generate-log.js +41 -2
- package/dist/common/logging/generate-log.js.map +1 -1
- package/package.json +2 -2
- package/src/common/errors/mosaic-errors.ts +8 -0
- package/src/common/helpers/object-helpers.spec.ts +120 -1
- package/src/common/helpers/object-helpers.ts +33 -0
- package/src/common/logging/generate-log.ts +49 -3
- package/src/common/logging/logger.spec.ts +233 -0
|
@@ -40,5 +40,13 @@ export declare const MosaicErrors: {
|
|
|
40
40
|
readonly message: "This is a wrapper error for the original unhandled error of unsupported type.";
|
|
41
41
|
readonly code: "ERROR_WRAPPER";
|
|
42
42
|
};
|
|
43
|
+
readonly ValueIsNotObject: {
|
|
44
|
+
readonly message: "The %s is not an object.";
|
|
45
|
+
readonly code: "VALUE_IS_NOT_OBJECT";
|
|
46
|
+
};
|
|
47
|
+
readonly ObjectIsMissingProperties: {
|
|
48
|
+
readonly message: "The %s is missing required properties: %s.";
|
|
49
|
+
readonly code: "OBJECT_IS_MISSING_PROPERTIES";
|
|
50
|
+
};
|
|
43
51
|
};
|
|
44
52
|
//# sourceMappingURL=mosaic-errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mosaic-errors.d.ts","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"mosaic-errors.d.ts","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDf,CAAC"}
|
|
@@ -45,5 +45,13 @@ exports.MosaicErrors = {
|
|
|
45
45
|
message: 'This is a wrapper error for the original unhandled error of unsupported type.',
|
|
46
46
|
code: 'ERROR_WRAPPER',
|
|
47
47
|
},
|
|
48
|
+
ValueIsNotObject: {
|
|
49
|
+
message: 'The %s is not an object.',
|
|
50
|
+
code: 'VALUE_IS_NOT_OBJECT',
|
|
51
|
+
},
|
|
52
|
+
ObjectIsMissingProperties: {
|
|
53
|
+
message: 'The %s is missing required properties: %s.',
|
|
54
|
+
code: 'OBJECT_IS_MISSING_PROPERTIES',
|
|
55
|
+
},
|
|
48
56
|
};
|
|
49
57
|
//# sourceMappingURL=mosaic-errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mosaic-errors.js","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACU,QAAA,YAAY,GAAG;IAC1B,mBAAmB,EAAE;QACnB,OAAO,EACL,qFAAqF;QACvF,IAAI,EAAE,uBAAuB;KAC9B;IACD,sBAAsB,EAAE;QACtB,OAAO,EACL,uFAAuF;QACzF,IAAI,EAAE,0BAA0B;KACjC;IACD,cAAc,EAAE;QACd,OAAO,EACL,sEAAsE;QACxE,IAAI,EAAE,iBAAiB;KACxB;IACD,2GAA2G;IAC3G,wBAAwB,EAAE;QACxB,OAAO,EACL,gHAAgH;QAClH,IAAI,EAAE,4BAA4B;KACnC;IACD,sFAAsF;IACtF,8BAA8B,EAAE;QAC9B,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,mCAAmC;KAC1C;IACD,uBAAuB,EAAE;QACvB,OAAO,EACL,+HAA+H;QACjI,IAAI,EAAE,2BAA2B;KAClC;IACD,YAAY,EAAE;QACZ,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,eAAe;KACtB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,kBAAkB;KACzB;IACD,YAAY,EAAE;QACZ,OAAO,EACL,+EAA+E;QACjF,IAAI,EAAE,eAAe;KACtB;CACO,CAAC"}
|
|
1
|
+
{"version":3,"file":"mosaic-errors.js","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACU,QAAA,YAAY,GAAG;IAC1B,mBAAmB,EAAE;QACnB,OAAO,EACL,qFAAqF;QACvF,IAAI,EAAE,uBAAuB;KAC9B;IACD,sBAAsB,EAAE;QACtB,OAAO,EACL,uFAAuF;QACzF,IAAI,EAAE,0BAA0B;KACjC;IACD,cAAc,EAAE;QACd,OAAO,EACL,sEAAsE;QACxE,IAAI,EAAE,iBAAiB;KACxB;IACD,2GAA2G;IAC3G,wBAAwB,EAAE;QACxB,OAAO,EACL,gHAAgH;QAClH,IAAI,EAAE,4BAA4B;KACnC;IACD,sFAAsF;IACtF,8BAA8B,EAAE;QAC9B,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,mCAAmC;KAC1C;IACD,uBAAuB,EAAE;QACvB,OAAO,EACL,+HAA+H;QACjI,IAAI,EAAE,2BAA2B;KAClC;IACD,YAAY,EAAE;QACZ,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,eAAe;KACtB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,kBAAkB;KACzB;IACD,YAAY,EAAE;QACZ,OAAO,EACL,+EAA+E;QACjF,IAAI,EAAE,eAAe;KACtB;IACD,gBAAgB,EAAE;QAChB,OAAO,EAAE,0BAA0B;QACnC,IAAI,EAAE,qBAAqB;KAC5B;IACD,yBAAyB,EAAE;QACzB,OAAO,EAAE,4CAA4C;QACrD,IAAI,EAAE,8BAA8B;KACrC;CACO,CAAC"}
|
|
@@ -43,4 +43,12 @@ export declare const pick: <T extends Record<string, unknown>, U extends keyof T
|
|
|
43
43
|
* @param map mapping function that will return a partial object for the property
|
|
44
44
|
*/
|
|
45
45
|
export declare const conditional: (condition: boolean, map: () => Dict<unknown>) => false | Dict<unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* Asserts that object has specific properties. Resulting object is assumed to
|
|
48
|
+
* have all properties, even optional, resulting in Required<T> type.
|
|
49
|
+
* @param value object to be asserted.
|
|
50
|
+
* @param properties properties to be checked.
|
|
51
|
+
* @param identifier object identifier to be used in error messages.
|
|
52
|
+
*/
|
|
53
|
+
export declare function assertObjectHasProperties<T>(object: unknown, properties: (keyof T)[], objectDescription?: string): asserts object is Required<T>;
|
|
46
54
|
//# sourceMappingURL=object-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-helpers.d.ts","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"object-helpers.d.ts","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC;;GAEG;AACH,eAAO,MAAM,oBAAoB,oCAQhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,oCAQjC,CAAC;AAEF;;;GAGG;AAEH,eAAO,MAAM,aAAa,6BAA4B,OAErD,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,GAEb,OAAO,CAAC,KAAK,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAIzC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,qGAShB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,cACX,OAAO,OACb,MAAM,KAAK,OAAO,CAAC,KACvB,KAAK,GAAG,KAAK,OAAO,CAEtB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EACzC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EACvB,iBAAiB,SAAiB,GACjC,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,CAmB/B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.conditional = exports.pick = exports.assertDictionary = exports.isEmptyObject = exports.removeEmptyProperties = exports.removeNullProperties = void 0;
|
|
3
|
+
exports.assertObjectHasProperties = exports.conditional = exports.pick = exports.assertDictionary = exports.isEmptyObject = exports.removeEmptyProperties = exports.removeNullProperties = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
4
5
|
const string_helpers_1 = require("./string-helpers");
|
|
5
6
|
/**
|
|
6
7
|
* Removes all properties with null value from object and returns a new object
|
|
@@ -82,4 +83,21 @@ const conditional = (condition, map) => {
|
|
|
82
83
|
return condition && map();
|
|
83
84
|
};
|
|
84
85
|
exports.conditional = conditional;
|
|
86
|
+
/**
|
|
87
|
+
* Asserts that object has specific properties. Resulting object is assumed to
|
|
88
|
+
* have all properties, even optional, resulting in Required<T> type.
|
|
89
|
+
* @param value object to be asserted.
|
|
90
|
+
* @param properties properties to be checked.
|
|
91
|
+
* @param identifier object identifier to be used in error messages.
|
|
92
|
+
*/
|
|
93
|
+
function assertObjectHasProperties(object, properties, objectDescription = 'passed value') {
|
|
94
|
+
if (object === null || typeof object !== 'object' || Array.isArray(object)) {
|
|
95
|
+
throw new errors_1.MosaicError(Object.assign(Object.assign({}, errors_1.MosaicErrors.ValueIsNotObject), { messageParams: [objectDescription] }));
|
|
96
|
+
}
|
|
97
|
+
const missingProperties = properties.filter((property) => !(property in object) || !object[property]);
|
|
98
|
+
if (missingProperties.length > 0) {
|
|
99
|
+
throw new errors_1.MosaicError(Object.assign(Object.assign({}, errors_1.MosaicErrors.ObjectIsMissingProperties), { messageParams: [objectDescription, missingProperties.join(', ')] }));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.assertObjectHasProperties = assertObjectHasProperties;
|
|
85
103
|
//# sourceMappingURL=object-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-helpers.js","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"object-helpers.js","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-log.d.ts","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"generate-log.d.ts","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAc,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAW5D;;GAEG;AACH,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,YAAY,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC;CAC7B;AA4CD;;GAEG;AACH,eAAO,MAAM,WAAW,WACd,iBAAiB,YACf,kBAAkB,kBACZ,aAAa,EAAE,KAC9B,GAAG,GAAG,SAyER,CAAC"}
|
|
@@ -8,6 +8,7 @@ const moment_1 = __importDefault(require("moment"));
|
|
|
8
8
|
const serialize_error_1 = require("serialize-error");
|
|
9
9
|
const helpers_1 = require("../helpers");
|
|
10
10
|
const log_level_1 = require("./log-level");
|
|
11
|
+
const log_retention_1 = require("./log-retention");
|
|
11
12
|
const mask_middleware_1 = require("./mask-middleware");
|
|
12
13
|
const parseTimestamp = (timestamp) => {
|
|
13
14
|
var _a;
|
|
@@ -19,6 +20,40 @@ const parseTimestamp = (timestamp) => {
|
|
|
19
20
|
return now;
|
|
20
21
|
}
|
|
21
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* If value.message exists, object type and is it a empty object return true
|
|
25
|
+
* If value.message exists, object type and object has any of LogMessage properties(message,logtime,retention,context,details) with correct type then return true
|
|
26
|
+
* otherwise return false
|
|
27
|
+
*/
|
|
28
|
+
const isLikeLogMessage = (value) => {
|
|
29
|
+
return (!!value &&
|
|
30
|
+
typeof value === 'object' &&
|
|
31
|
+
((0, helpers_1.isEmptyObject)(value) ||
|
|
32
|
+
('message' in value && typeof value.message === 'string') ||
|
|
33
|
+
('logtime' in value &&
|
|
34
|
+
(typeof value.logtime === 'string' || value.logtime instanceof Date)) ||
|
|
35
|
+
('retention' in value &&
|
|
36
|
+
typeof value.retention === 'string' &&
|
|
37
|
+
Object.values(log_retention_1.LogRetention).includes(value.retention)) ||
|
|
38
|
+
('context' in value && typeof value.context === 'string') ||
|
|
39
|
+
('details' in value && typeof value.details === 'object')));
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Generates a LogMessage property called details object with correct values
|
|
43
|
+
*/
|
|
44
|
+
const generateLogMessageDetailsProp = (inputMessage) => {
|
|
45
|
+
const invalidMessage = JSON.stringify(inputMessage);
|
|
46
|
+
const longMessageClarification = invalidMessage.length <= 1000
|
|
47
|
+
? ''
|
|
48
|
+
: `because the message is too long (${invalidMessage.length} characters), first 1000 characters are `;
|
|
49
|
+
const hint = `The message passed into the logger is of the invalid format. It is stringified and ${longMessageClarification}logged as details.invalidMessage.`;
|
|
50
|
+
return {
|
|
51
|
+
details: {
|
|
52
|
+
invalidMessage: invalidMessage.slice(0, 1000),
|
|
53
|
+
hint: hint,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
};
|
|
22
57
|
/**
|
|
23
58
|
* Generates a default log object without relying on config values.
|
|
24
59
|
*/
|
|
@@ -26,7 +61,9 @@ const generateLog = (values, masking, logMiddleware) => {
|
|
|
26
61
|
var _a;
|
|
27
62
|
const { message: msg, logtime, context, details, } = typeof values.message === 'string'
|
|
28
63
|
? { message: values.message }
|
|
29
|
-
: values.message
|
|
64
|
+
: isLikeLogMessage(values.message)
|
|
65
|
+
? values.message
|
|
66
|
+
: generateLogMessageDetailsProp(values.message);
|
|
30
67
|
let logMessage = {
|
|
31
68
|
logtime: parseTimestamp(logtime),
|
|
32
69
|
loglevel: log_level_1.LogLevel[values.level],
|
|
@@ -36,7 +73,9 @@ const generateLog = (values, masking, logMiddleware) => {
|
|
|
36
73
|
// sensitive properties
|
|
37
74
|
message: !(0, helpers_1.isNullOrWhitespace)(msg)
|
|
38
75
|
? msg
|
|
39
|
-
: values.error
|
|
76
|
+
: values.error &&
|
|
77
|
+
values.error.message &&
|
|
78
|
+
typeof values.error.message === 'string'
|
|
40
79
|
? values.error.message
|
|
41
80
|
: 'no message',
|
|
42
81
|
details: (0, helpers_1.isEmptyObject)(details) ? undefined : details,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-log.js","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,qDAAiD;AACjD,wCAA+D;AAE/D,2CAAuC;
|
|
1
|
+
{"version":3,"file":"generate-log.js","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-service-common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0-rc.0",
|
|
4
4
|
"description": "Common helpers and PostgreSQL-related functionality",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "32853a01e5b6de8cb3712ea5e1bd75780df8d59d"
|
|
74
74
|
}
|
|
@@ -50,4 +50,12 @@ export const MosaicErrors = {
|
|
|
50
50
|
'This is a wrapper error for the original unhandled error of unsupported type.',
|
|
51
51
|
code: 'ERROR_WRAPPER',
|
|
52
52
|
},
|
|
53
|
+
ValueIsNotObject: {
|
|
54
|
+
message: 'The %s is not an object.',
|
|
55
|
+
code: 'VALUE_IS_NOT_OBJECT',
|
|
56
|
+
},
|
|
57
|
+
ObjectIsMissingProperties: {
|
|
58
|
+
message: 'The %s is missing required properties: %s.',
|
|
59
|
+
code: 'OBJECT_IS_MISSING_PROPERTIES',
|
|
60
|
+
},
|
|
53
61
|
} as const;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import 'jest-extended';
|
|
2
|
+
import { MosaicErrors } from '../errors';
|
|
2
3
|
import {
|
|
4
|
+
assertObjectHasProperties,
|
|
3
5
|
conditional,
|
|
4
6
|
isEmptyObject,
|
|
5
7
|
removeEmptyProperties,
|
|
6
8
|
removeNullProperties,
|
|
7
9
|
} from './object-helpers';
|
|
8
|
-
import { toSerializeEqual } from './test-helpers';
|
|
10
|
+
import { expectFailure, toSerializeEqual } from './test-helpers';
|
|
9
11
|
|
|
10
12
|
class TestClass {
|
|
11
13
|
public test?: string;
|
|
@@ -135,4 +137,121 @@ describe('Object Helpers', () => {
|
|
|
135
137
|
});
|
|
136
138
|
});
|
|
137
139
|
});
|
|
140
|
+
|
|
141
|
+
describe('assertObjectHasProperties', () => {
|
|
142
|
+
interface Test {
|
|
143
|
+
propA: string;
|
|
144
|
+
propB?: { test: string };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
it('assert interface object as interface -> no type error', () => {
|
|
148
|
+
// Arrange
|
|
149
|
+
const obj: Test = { propA: 'test A', propB: { test: 'test B' } };
|
|
150
|
+
|
|
151
|
+
// Act
|
|
152
|
+
assertObjectHasProperties<Test>(obj, ['propA', 'propB'], 'test object');
|
|
153
|
+
|
|
154
|
+
// Assert
|
|
155
|
+
// Without type assertion this would have been underlined with error `obj.propB' is possibly 'undefined'.`
|
|
156
|
+
expect(obj.propB.test).toBeTruthy();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('assert index signature object as interface -> no type error', () => {
|
|
160
|
+
// Arrange
|
|
161
|
+
const obj: {
|
|
162
|
+
[str: string]: unknown;
|
|
163
|
+
} = { propA: 'test A', propB: { test: 'test B' } };
|
|
164
|
+
|
|
165
|
+
// Act
|
|
166
|
+
assertObjectHasProperties<Test>(obj, ['propA', 'propB'], 'test object');
|
|
167
|
+
|
|
168
|
+
// Assert
|
|
169
|
+
// Without type assertion this would have been underlined with error `obj.propB' is possibly 'undefined'.`
|
|
170
|
+
expect(obj.propB.test).toBeTruthy();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('assert unknown object as interface -> no type error', () => {
|
|
174
|
+
// Arrange
|
|
175
|
+
const obj: unknown = { propA: 'test A', propB: { test: 'test B' } };
|
|
176
|
+
|
|
177
|
+
// Act
|
|
178
|
+
assertObjectHasProperties<Test>(obj, ['propA', 'propB'], 'test object');
|
|
179
|
+
|
|
180
|
+
// Assert
|
|
181
|
+
// Without type assertion this would have been underlined with error `obj.propB' is possibly 'undefined'.`
|
|
182
|
+
expect(obj.propB.test).toBeTruthy();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('assert empty object as interface -> missing properties error', () => {
|
|
186
|
+
// Act
|
|
187
|
+
const error = expectFailure(() =>
|
|
188
|
+
assertObjectHasProperties<Test>({}, ['propA', 'propB'], 'test object'),
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Assert
|
|
192
|
+
expect(error).toMatchObject({
|
|
193
|
+
message:
|
|
194
|
+
'The test object is missing required properties: propA, propB.',
|
|
195
|
+
code: MosaicErrors.ObjectIsMissingProperties.code,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('assert half-empty object as interface -> missing properties error', () => {
|
|
200
|
+
// Act
|
|
201
|
+
const error = expectFailure(() =>
|
|
202
|
+
assertObjectHasProperties<Test>({ propA: 'test A' }, [
|
|
203
|
+
'propA',
|
|
204
|
+
'propB',
|
|
205
|
+
]),
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// Assert
|
|
209
|
+
expect(error).toMatchObject({
|
|
210
|
+
// Also testing default object description
|
|
211
|
+
message: 'The passed value is missing required properties: propB.',
|
|
212
|
+
code: MosaicErrors.ObjectIsMissingProperties.code,
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it.each([null, undefined])(
|
|
217
|
+
'assert object with %p value as interface -> missing properties error',
|
|
218
|
+
(emptyValue) => {
|
|
219
|
+
// Act
|
|
220
|
+
const error = expectFailure(() =>
|
|
221
|
+
assertObjectHasProperties<Test>(
|
|
222
|
+
{ propA: 'test A', propB: emptyValue },
|
|
223
|
+
['propA', 'propB'],
|
|
224
|
+
'test object',
|
|
225
|
+
),
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
// Assert
|
|
229
|
+
expect(error).toMatchObject({
|
|
230
|
+
message: 'The test object is missing required properties: propB.',
|
|
231
|
+
code: MosaicErrors.ObjectIsMissingProperties.code,
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
237
|
+
it.each([null, undefined, '', ' ', 123, true, [], () => {}])(
|
|
238
|
+
'assert non-object %p -> not object error',
|
|
239
|
+
(value) => {
|
|
240
|
+
// Act
|
|
241
|
+
const error = expectFailure(() =>
|
|
242
|
+
assertObjectHasProperties<Test>(
|
|
243
|
+
value,
|
|
244
|
+
['propA', 'propB'],
|
|
245
|
+
'test object',
|
|
246
|
+
),
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// Assert
|
|
250
|
+
expect(error).toMatchObject({
|
|
251
|
+
message: 'The test object is not an object.',
|
|
252
|
+
code: MosaicErrors.ValueIsNotObject.code,
|
|
253
|
+
});
|
|
254
|
+
},
|
|
255
|
+
);
|
|
256
|
+
});
|
|
138
257
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MosaicError, MosaicErrors } from '../errors';
|
|
1
2
|
import { Dict } from '../types';
|
|
2
3
|
import { isNullOrWhitespace } from './string-helpers';
|
|
3
4
|
|
|
@@ -89,3 +90,35 @@ export const conditional = (
|
|
|
89
90
|
): false | Dict<unknown> => {
|
|
90
91
|
return condition && map();
|
|
91
92
|
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Asserts that object has specific properties. Resulting object is assumed to
|
|
96
|
+
* have all properties, even optional, resulting in Required<T> type.
|
|
97
|
+
* @param value object to be asserted.
|
|
98
|
+
* @param properties properties to be checked.
|
|
99
|
+
* @param identifier object identifier to be used in error messages.
|
|
100
|
+
*/
|
|
101
|
+
export function assertObjectHasProperties<T>(
|
|
102
|
+
object: unknown,
|
|
103
|
+
properties: (keyof T)[],
|
|
104
|
+
objectDescription = 'passed value',
|
|
105
|
+
): asserts object is Required<T> {
|
|
106
|
+
if (object === null || typeof object !== 'object' || Array.isArray(object)) {
|
|
107
|
+
throw new MosaicError({
|
|
108
|
+
...MosaicErrors.ValueIsNotObject,
|
|
109
|
+
messageParams: [objectDescription],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const missingProperties = properties.filter(
|
|
114
|
+
(property) =>
|
|
115
|
+
!(property in object) || !(object as Record<keyof T, unknown>)[property],
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (missingProperties.length > 0) {
|
|
119
|
+
throw new MosaicError({
|
|
120
|
+
...MosaicErrors.ObjectIsMissingProperties,
|
|
121
|
+
messageParams: [objectDescription, missingProperties.join(', ')],
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -5,7 +5,7 @@ import { Log } from './log';
|
|
|
5
5
|
import { LogLevel } from './log-level';
|
|
6
6
|
import { LogMessage } from './log-message';
|
|
7
7
|
import { LogRetention } from './log-retention';
|
|
8
|
-
import { MaskMiddleware,
|
|
8
|
+
import { MaskMiddleware, MaskOptions, maskObject } from './mask-middleware';
|
|
9
9
|
import { SkipMaskMiddleware } from './skip-mask-middleware';
|
|
10
10
|
|
|
11
11
|
const parseTimestamp = (timestamp: string | Date | undefined): string => {
|
|
@@ -45,6 +45,48 @@ export interface LogMiddleware {
|
|
|
45
45
|
(log: Log): Log | undefined;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* If value.message exists, object type and is it a empty object return true
|
|
50
|
+
* If value.message exists, object type and object has any of LogMessage properties(message,logtime,retention,context,details) with correct type then return true
|
|
51
|
+
* otherwise return false
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
const isLikeLogMessage = (value: unknown): boolean => {
|
|
55
|
+
return (
|
|
56
|
+
!!value &&
|
|
57
|
+
typeof value === 'object' &&
|
|
58
|
+
(isEmptyObject(value) ||
|
|
59
|
+
('message' in value && typeof value.message === 'string') ||
|
|
60
|
+
('logtime' in value &&
|
|
61
|
+
(typeof value.logtime === 'string' || value.logtime instanceof Date)) ||
|
|
62
|
+
('retention' in value &&
|
|
63
|
+
typeof value.retention === 'string' &&
|
|
64
|
+
Object.values(LogRetention).includes(
|
|
65
|
+
value.retention as LogRetention,
|
|
66
|
+
)) ||
|
|
67
|
+
('context' in value && typeof value.context === 'string') ||
|
|
68
|
+
('details' in value && typeof value.details === 'object'))
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generates a LogMessage property called details object with correct values
|
|
74
|
+
*/
|
|
75
|
+
const generateLogMessageDetailsProp = (inputMessage: unknown): object => {
|
|
76
|
+
const invalidMessage = JSON.stringify(inputMessage);
|
|
77
|
+
const longMessageClarification =
|
|
78
|
+
invalidMessage.length <= 1000
|
|
79
|
+
? ''
|
|
80
|
+
: `because the message is too long (${invalidMessage.length} characters), first 1000 characters are `;
|
|
81
|
+
const hint = `The message passed into the logger is of the invalid format. It is stringified and ${longMessageClarification}logged as details.invalidMessage.`;
|
|
82
|
+
return {
|
|
83
|
+
details: {
|
|
84
|
+
invalidMessage: invalidMessage.slice(0, 1000),
|
|
85
|
+
hint: hint,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
48
90
|
/**
|
|
49
91
|
* Generates a default log object without relying on config values.
|
|
50
92
|
*/
|
|
@@ -60,7 +102,9 @@ export const generateLog = (
|
|
|
60
102
|
details,
|
|
61
103
|
}: LogMessage = typeof values.message === 'string'
|
|
62
104
|
? { message: values.message }
|
|
63
|
-
: values.message
|
|
105
|
+
: isLikeLogMessage(values.message)
|
|
106
|
+
? values.message
|
|
107
|
+
: generateLogMessageDetailsProp(values.message);
|
|
64
108
|
|
|
65
109
|
let logMessage: Log = {
|
|
66
110
|
logtime: parseTimestamp(logtime),
|
|
@@ -71,7 +115,9 @@ export const generateLog = (
|
|
|
71
115
|
// sensitive properties
|
|
72
116
|
message: !isNullOrWhitespace(msg)
|
|
73
117
|
? msg
|
|
74
|
-
: values.error
|
|
118
|
+
: values.error &&
|
|
119
|
+
values.error.message &&
|
|
120
|
+
typeof values.error.message === 'string'
|
|
75
121
|
? values.error.message
|
|
76
122
|
: 'no message',
|
|
77
123
|
details: isEmptyObject(details) ? undefined : details,
|
|
@@ -1364,4 +1364,237 @@ describe('Logger', () => {
|
|
|
1364
1364
|
});
|
|
1365
1365
|
});
|
|
1366
1366
|
});
|
|
1367
|
+
|
|
1368
|
+
describe(`error log when the type of 'message' is unknown`, () => {
|
|
1369
|
+
it('error log message with string message value -> set string value for message', () => {
|
|
1370
|
+
// Act
|
|
1371
|
+
logger.error('Hello World');
|
|
1372
|
+
|
|
1373
|
+
// Assert
|
|
1374
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1375
|
+
|
|
1376
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1377
|
+
|
|
1378
|
+
const referenceObject = {
|
|
1379
|
+
logtime: loggedObject.logtime,
|
|
1380
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1381
|
+
retention: LogRetention.Medium,
|
|
1382
|
+
message: 'Hello World',
|
|
1383
|
+
context: 'LoggerTests',
|
|
1384
|
+
component: 'navy-asset-service_test',
|
|
1385
|
+
};
|
|
1386
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1387
|
+
});
|
|
1388
|
+
|
|
1389
|
+
it('error log message with boolean message value -> convert boolean value to string value for message', () => {
|
|
1390
|
+
// Act
|
|
1391
|
+
logger.error(true as any);
|
|
1392
|
+
|
|
1393
|
+
// Assert
|
|
1394
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1395
|
+
|
|
1396
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1397
|
+
|
|
1398
|
+
const referenceObject = {
|
|
1399
|
+
logtime: loggedObject.logtime,
|
|
1400
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1401
|
+
retention: LogRetention.Medium,
|
|
1402
|
+
message: 'no message',
|
|
1403
|
+
details: {
|
|
1404
|
+
invalidMessage: 'true',
|
|
1405
|
+
hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
|
|
1406
|
+
},
|
|
1407
|
+
context: 'LoggerTests',
|
|
1408
|
+
component: 'navy-asset-service_test',
|
|
1409
|
+
};
|
|
1410
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
it('error log message with number message value -> convert number value to string value for message', () => {
|
|
1414
|
+
// Act
|
|
1415
|
+
logger.error(100 as any);
|
|
1416
|
+
|
|
1417
|
+
// Assert
|
|
1418
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1419
|
+
|
|
1420
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1421
|
+
|
|
1422
|
+
const referenceObject = {
|
|
1423
|
+
logtime: loggedObject.logtime,
|
|
1424
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1425
|
+
retention: LogRetention.Medium,
|
|
1426
|
+
message: 'no message',
|
|
1427
|
+
details: {
|
|
1428
|
+
invalidMessage: '100',
|
|
1429
|
+
hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
|
|
1430
|
+
},
|
|
1431
|
+
context: 'LoggerTests',
|
|
1432
|
+
component: 'navy-asset-service_test',
|
|
1433
|
+
};
|
|
1434
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1435
|
+
});
|
|
1436
|
+
|
|
1437
|
+
it('error log message with empty object message value -> convert object value to string value for message', () => {
|
|
1438
|
+
// Act
|
|
1439
|
+
logger.error({} as any);
|
|
1440
|
+
|
|
1441
|
+
// Assert
|
|
1442
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1443
|
+
|
|
1444
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1445
|
+
|
|
1446
|
+
const referenceObject = {
|
|
1447
|
+
logtime: loggedObject.logtime,
|
|
1448
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1449
|
+
retention: LogRetention.Medium,
|
|
1450
|
+
message: 'no message',
|
|
1451
|
+
context: 'LoggerTests',
|
|
1452
|
+
component: 'navy-asset-service_test',
|
|
1453
|
+
};
|
|
1454
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1455
|
+
});
|
|
1456
|
+
|
|
1457
|
+
it('error log message with object message having string value -> set string value for message', () => {
|
|
1458
|
+
// Act
|
|
1459
|
+
logger.error({ message: 'Hello World' } as any);
|
|
1460
|
+
|
|
1461
|
+
// Assert
|
|
1462
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1463
|
+
|
|
1464
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1465
|
+
|
|
1466
|
+
const referenceObject = {
|
|
1467
|
+
logtime: loggedObject.logtime,
|
|
1468
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1469
|
+
retention: LogRetention.Medium,
|
|
1470
|
+
message: 'Hello World',
|
|
1471
|
+
context: 'LoggerTests',
|
|
1472
|
+
component: 'navy-asset-service_test',
|
|
1473
|
+
};
|
|
1474
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1475
|
+
});
|
|
1476
|
+
|
|
1477
|
+
it('error log message with object message having number value -> set stringified object value for message', () => {
|
|
1478
|
+
// Act
|
|
1479
|
+
logger.error({ message: 100 } as any);
|
|
1480
|
+
|
|
1481
|
+
// Assert
|
|
1482
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1483
|
+
|
|
1484
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1485
|
+
|
|
1486
|
+
const referenceObject = {
|
|
1487
|
+
logtime: loggedObject.logtime,
|
|
1488
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1489
|
+
retention: LogRetention.Medium,
|
|
1490
|
+
message: 'no message',
|
|
1491
|
+
details: {
|
|
1492
|
+
invalidMessage: '{"message":100}',
|
|
1493
|
+
hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
|
|
1494
|
+
},
|
|
1495
|
+
context: 'LoggerTests',
|
|
1496
|
+
component: 'navy-asset-service_test',
|
|
1497
|
+
};
|
|
1498
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
it('error log message with object message having boolean value -> set stringified object value for message', () => {
|
|
1502
|
+
// Act
|
|
1503
|
+
logger.error({ message: true } as any);
|
|
1504
|
+
|
|
1505
|
+
// Assert
|
|
1506
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1507
|
+
|
|
1508
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1509
|
+
|
|
1510
|
+
const referenceObject = {
|
|
1511
|
+
logtime: loggedObject.logtime,
|
|
1512
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1513
|
+
retention: LogRetention.Medium,
|
|
1514
|
+
message: 'no message',
|
|
1515
|
+
details: {
|
|
1516
|
+
invalidMessage: '{"message":true}',
|
|
1517
|
+
hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
|
|
1518
|
+
},
|
|
1519
|
+
context: 'LoggerTests',
|
|
1520
|
+
component: 'navy-asset-service_test',
|
|
1521
|
+
};
|
|
1522
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1525
|
+
it('error log message with object message having different format of values -> set stringified object value for message', () => {
|
|
1526
|
+
// Act
|
|
1527
|
+
logger.error({ message: {}, test: 'test prop' } as any);
|
|
1528
|
+
|
|
1529
|
+
// Assert
|
|
1530
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1531
|
+
|
|
1532
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1533
|
+
|
|
1534
|
+
const referenceObject = {
|
|
1535
|
+
logtime: loggedObject.logtime,
|
|
1536
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1537
|
+
retention: LogRetention.Medium,
|
|
1538
|
+
message: 'no message',
|
|
1539
|
+
details: {
|
|
1540
|
+
invalidMessage: '{"message":{},"test":"test prop"}',
|
|
1541
|
+
hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
|
|
1542
|
+
},
|
|
1543
|
+
context: 'LoggerTests',
|
|
1544
|
+
component: 'navy-asset-service_test',
|
|
1545
|
+
};
|
|
1546
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1547
|
+
});
|
|
1548
|
+
|
|
1549
|
+
it('error log message with non string format and more than 1000 characters -> set stringified and first 1000 characters are set for message', () => {
|
|
1550
|
+
const randomString =
|
|
1551
|
+
'TNwCBNAVmXXzZOaPiKGJTQyueACishwwLnZMPUaniVtTgOlqMwlqcGvBNABRyJFOVTTgBfEeZuCPHaNMuwTgQpduvKtPykFSuiLTQkRyeEnPwrGThTdlmiObxmpFkZygfXAwezfsbKxioablETznFcRXtOJmKFWFtiacqcdEkDooycxaiOkyVPhTUCsCTelggTzPrTTBSazsTpnyKQmoLikEueSNyXxuhEAAuwQGdStXdIxVRIxTpFkgePWLheWSxJkZUkJrbvpsJyEulQWRclmRbDrcVEKlMDFQsADwnJCkNPhLdOyagsruMwcJdJaSlisNmNEmNHGfNTTzTScomxFbDKTyaPXuxXrvtCooLqbXWfQnhnwcyRuSLpoRfMXeDRFCdTeVkbNuXKdMsNqESXrrSlEtvmAkHdXGmHmHiyBsSwaFhCCmgwgniBQQKemOFvZckaOIRADroRUGWLAJNyhTpVaFvJbuCNEIJNToWuiniTZUpMJOOTNMRhABJnpQHfLGsAWJTtWtBdBxZCXxBhaClzORcgpstBggDUwCtpagvzCIGbKDfDJhWWxcLKNbgBxzzNoaGlrTipoxbKKlJGESGxlJOxwquTRaEvIckdUOBebKczCEifeZiREUalMSnrPLVuunyZzIXFPDsePJIMXyvOzvlXgkqhBtgVbfAqmsbvkPVKUXKXtiDlQCfAnfKzETgfHhxsdXOevPXCnxqFEpmWvxaQnXcyUCcLgEvLSioLbfLWutRAfJJPfCTRhrVwwTDFMgnJAGrreTOXRDtouHysurRUdspnwsKuqNeozvfkaWkfyyZpAdBsUgaVqpTJzlXipLdrxtqiiATveTnbuAzPTatNTCwyJTTNSklHTVVndNqknyQIbULeWgNWHedthZeQFKvdXtQVVuHJfvhSJfuXOVxEfKpzezSkfqHZgWPRfUtbLFbNlJSfOgUJdcvxnliUZOCQilOPmzGxOeyaWiZFOmumwcbHmWulcS';
|
|
1552
|
+
// Act
|
|
1553
|
+
logger.error({ message: {}, testMsg: randomString } as any);
|
|
1554
|
+
|
|
1555
|
+
// Assert
|
|
1556
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1557
|
+
|
|
1558
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1559
|
+
|
|
1560
|
+
const referenceObject = {
|
|
1561
|
+
logtime: loggedObject.logtime,
|
|
1562
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1563
|
+
retention: LogRetention.Medium,
|
|
1564
|
+
message: 'no message',
|
|
1565
|
+
details: {
|
|
1566
|
+
invalidMessage:
|
|
1567
|
+
'{"message":{},"testMsg":"TNwCBNAVmXXzZOaPiKGJTQyueACishwwLnZMPUaniVtTgOlqMwlqcGvBNABRyJFOVTTgBfEeZuCPHaNMuwTgQpduvKtPykFSuiLTQkRyeEnPwrGThTdlmiObxmpFkZygfXAwezfsbKxioablETznFcRXtOJmKFWFtiacqcdEkDooycxaiOkyVPhTUCsCTelggTzPrTTBSazsTpnyKQmoLikEueSNyXxuhEAAuwQGdStXdIxVRIxTpFkgePWLheWSxJkZUkJrbvpsJyEulQWRclmRbDrcVEKlMDFQsADwnJCkNPhLdOyagsruMwcJdJaSlisNmNEmNHGfNTTzTScomxFbDKTyaPXuxXrvtCooLqbXWfQnhnwcyRuSLpoRfMXeDRFCdTeVkbNuXKdMsNqESXrrSlEtvmAkHdXGmHmHiyBsSwaFhCCmgwgniBQQKemOFvZckaOIRADroRUGWLAJNyhTpVaFvJbuCNEIJNToWuiniTZUpMJOOTNMRhABJnpQHfLGsAWJTtWtBdBxZCXxBhaClzORcgpstBggDUwCtpagvzCIGbKDfDJhWWxcLKNbgBxzzNoaGlrTipoxbKKlJGESGxlJOxwquTRaEvIckdUOBebKczCEifeZiREUalMSnrPLVuunyZzIXFPDsePJIMXyvOzvlXgkqhBtgVbfAqmsbvkPVKUXKXtiDlQCfAnfKzETgfHhxsdXOevPXCnxqFEpmWvxaQnXcyUCcLgEvLSioLbfLWutRAfJJPfCTRhrVwwTDFMgnJAGrreTOXRDtouHysurRUdspnwsKuqNeozvfkaWkfyyZpAdBsUgaVqpTJzlXipLdrxtqiiATveTnbuAzPTatNTCwyJTTNSklHTVVndNqknyQIbULeWgNWHedthZeQFKvdXtQVVuHJfvhSJfuXOVxEfKpzezSkfqHZgWPRfUtbLFbNlJSfOgUJdcvxnliUZOCQilOPm',
|
|
1568
|
+
hint: 'The message passed into the logger is of the invalid format. It is stringified and because the message is too long (1027 characters), first 1000 characters are logged as details.invalidMessage.',
|
|
1569
|
+
},
|
|
1570
|
+
context: 'LoggerTests',
|
|
1571
|
+
component: 'navy-asset-service_test',
|
|
1572
|
+
};
|
|
1573
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1574
|
+
expect(referenceObject.details.invalidMessage).toHaveLength(1000);
|
|
1575
|
+
});
|
|
1576
|
+
|
|
1577
|
+
it('error log message with non-string value and error object message also dont have string message property -> set no message as for message', () => {
|
|
1578
|
+
// Act
|
|
1579
|
+
const error = new Error();
|
|
1580
|
+
logger.error({ message: 600 } as any, error);
|
|
1581
|
+
|
|
1582
|
+
// Assert
|
|
1583
|
+
expect(consoleOverride).toHaveBeenCalledTimes(1);
|
|
1584
|
+
const loggedObject = getFirstMockResult<any>(consoleOverride);
|
|
1585
|
+
|
|
1586
|
+
const referenceObject = {
|
|
1587
|
+
logtime: loggedObject.logtime,
|
|
1588
|
+
loglevel: LogLevel[LogLevel.ERROR],
|
|
1589
|
+
retention: LogRetention.Medium,
|
|
1590
|
+
message: 'no message',
|
|
1591
|
+
context: 'LoggerTests',
|
|
1592
|
+
error: {
|
|
1593
|
+
message: 600,
|
|
1594
|
+
},
|
|
1595
|
+
component: 'navy-asset-service_test',
|
|
1596
|
+
};
|
|
1597
|
+
expect(loggedObject).toEqual(referenceObject);
|
|
1598
|
+
});
|
|
1599
|
+
});
|
|
1367
1600
|
});
|