ac-support-connector 1.0.13 → 1.0.14
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 +12 -0
- package/index.js +15 -5
- package/package.json +1 -1
- package/test/test.js +113 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [1.0.14](https://github.com/admiralcloud/ac-support-connector/compare/v1.0.13..v1.0.14) (2026-04-09 11:27:07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fix
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
* **Connector:** Improvements after CoPilot review | MP | [e09a77aa4871c89a05383f0f03b076a6ef2f63c3](https://github.com/admiralcloud/ac-support-connector/commit/e09a77aa4871c89a05383f0f03b076a6ef2f63c3)
|
|
8
|
+
Improvements after CoPilot review
|
|
9
|
+
Related issues:
|
|
10
|
+
* **Connector:** Add 2 new parameters - throwError, logger | MP | [982c057541f6e3cef22a661c0eb51403a899b2ef](https://github.com/admiralcloud/ac-support-connector/commit/982c057541f6e3cef22a661c0eb51403a899b2ef)
|
|
11
|
+
Set throwError as true per default, so errors are propagated. Allow custom loggers, default to console (as before)
|
|
12
|
+
Related issues:
|
|
1
13
|
## [1.0.13](https://github.com/admiralcloud/ac-support-connector/compare/v1.0.12..v1.0.13) (2026-04-04 10:19:59)
|
|
2
14
|
|
|
3
15
|
|
package/index.js
CHANGED
|
@@ -9,7 +9,7 @@ module.exports = {
|
|
|
9
9
|
|
|
10
10
|
aws: {},
|
|
11
11
|
|
|
12
|
-
init: async function({ serviceName, instanceId, sqsQueue = 'AC-SupportQueue', bucket, redisInstance, region = 'eu-central-1', profile = process.env['profile'], debug } = {}) {
|
|
12
|
+
init: async function({ serviceName, instanceId, sqsQueue = 'AC-SupportQueue', bucket, redisInstance, region = 'eu-central-1', profile = process.env['profile'], debug, logger = console, throwError = true } = {}) {
|
|
13
13
|
|
|
14
14
|
this.sqsQueue = sqsQueue
|
|
15
15
|
this.serviceName = serviceName || 'SupportConnector'
|
|
@@ -17,6 +17,12 @@ module.exports = {
|
|
|
17
17
|
this.redisInstance = redisInstance
|
|
18
18
|
this.cache = new NodeCache()
|
|
19
19
|
this.debugMode = debug
|
|
20
|
+
this.logger = {
|
|
21
|
+
info: logger?.info?.bind(logger) ?? console.info.bind(console),
|
|
22
|
+
warn: logger?.warn?.bind(logger) ?? console.warn.bind(console),
|
|
23
|
+
error: logger?.error?.bind(logger) ?? console.error.bind(console),
|
|
24
|
+
}
|
|
25
|
+
this.throwError = throwError
|
|
20
26
|
|
|
21
27
|
if (!debug) {
|
|
22
28
|
const client = new STSClient({
|
|
@@ -31,7 +37,8 @@ module.exports = {
|
|
|
31
37
|
availableLists: [{
|
|
32
38
|
name: sqsQueue,
|
|
33
39
|
fifo: true
|
|
34
|
-
}]
|
|
40
|
+
}],
|
|
41
|
+
throwError
|
|
35
42
|
}
|
|
36
43
|
if (profile) { sqsParams.profile = profile } // Optional AWS profile, see below
|
|
37
44
|
if (bucket) {
|
|
@@ -61,7 +68,7 @@ module.exports = {
|
|
|
61
68
|
})
|
|
62
69
|
}
|
|
63
70
|
await this.createMessage(ticket)
|
|
64
|
-
|
|
71
|
+
this.logger.warn(`Test Message ${identifier} sent`)
|
|
65
72
|
process.exit(0)
|
|
66
73
|
}
|
|
67
74
|
}
|
|
@@ -111,11 +118,14 @@ module.exports = {
|
|
|
111
118
|
}
|
|
112
119
|
try {
|
|
113
120
|
const response = await this.acsqs.sendSQSMessage({ name: this.sqsQueue, message: JSON.stringify(messagePayload), messageGroupId: (messageGroupId || this.serviceName) })
|
|
114
|
-
if (this.debugMode) {
|
|
121
|
+
if (this.debugMode) { this.logger.info(response) }
|
|
115
122
|
return response
|
|
116
123
|
}
|
|
117
124
|
catch(e) {
|
|
118
|
-
|
|
125
|
+
this.logger.error('%s | Subject %s | Failed %j', functionName, subject, e?.message)
|
|
126
|
+
if (this.throwError) {
|
|
127
|
+
throw e
|
|
128
|
+
}
|
|
119
129
|
}
|
|
120
130
|
}
|
|
121
131
|
}
|
package/package.json
CHANGED
package/test/test.js
CHANGED
|
@@ -7,7 +7,7 @@ function createFakeRedis() {
|
|
|
7
7
|
const store = new Map()
|
|
8
8
|
return {
|
|
9
9
|
async set(key, _value, exFlag, seconds, nxFlag) {
|
|
10
|
-
if (nxFlag === 'nx' && store.has(key)) return null
|
|
10
|
+
if (nxFlag === 'nx' && store.has(key)) { return null }
|
|
11
11
|
store.set(key, true)
|
|
12
12
|
setTimeout(() => store.delete(key), seconds * 1000)
|
|
13
13
|
return 'OK'
|
|
@@ -18,7 +18,7 @@ function createFakeRedis() {
|
|
|
18
18
|
|
|
19
19
|
const redisInstance = createFakeRedis()
|
|
20
20
|
|
|
21
|
-
const string1001 = new Array(
|
|
21
|
+
const string1001 = new Array(1100000).join('b')
|
|
22
22
|
|
|
23
23
|
function timeout(ms) {
|
|
24
24
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
@@ -38,7 +38,7 @@ describe('Basic tests', () => {
|
|
|
38
38
|
expect(response.message[0]).to.have.property('content', params.text)
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
-
it('Check truncated payload >
|
|
41
|
+
it('Check truncated payload > 1MB - should not throw an error', async() => {
|
|
42
42
|
const params = {
|
|
43
43
|
subject: 'Failed',
|
|
44
44
|
message: [{
|
|
@@ -153,6 +153,116 @@ describe('Block with Memory', () => {
|
|
|
153
153
|
})
|
|
154
154
|
|
|
155
155
|
|
|
156
|
+
describe('throwError behavior', () => {
|
|
157
|
+
const originalEnv = process.env.NODE_ENV
|
|
158
|
+
let fakeLogger
|
|
159
|
+
|
|
160
|
+
before(async() => {
|
|
161
|
+
fakeLogger = { errors: [], warns: [], error(...args) { this.errors.push(args) }, warn(...args) { this.warns.push(args) } }
|
|
162
|
+
await supCon.init({ debug: true, logger: fakeLogger })
|
|
163
|
+
process.env.NODE_ENV = 'production' // bypass early return in createMessage
|
|
164
|
+
supCon.acsqs = {
|
|
165
|
+
async sendSQSMessage() {
|
|
166
|
+
throw new Error('SQS failed')
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
after(() => {
|
|
172
|
+
process.env.NODE_ENV = originalEnv
|
|
173
|
+
delete supCon.acsqs
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('throwError: true - should throw on SQS failure', async() => {
|
|
177
|
+
supCon.throwError = true
|
|
178
|
+
fakeLogger.errors = []
|
|
179
|
+
let threw = false
|
|
180
|
+
try {
|
|
181
|
+
await supCon.createMessage({ subject: 'Test', text: 'Error' })
|
|
182
|
+
}
|
|
183
|
+
catch(e) {
|
|
184
|
+
threw = true
|
|
185
|
+
expect(e.message).to.equal('SQS failed')
|
|
186
|
+
}
|
|
187
|
+
expect(threw).to.be.true
|
|
188
|
+
expect(fakeLogger.errors).to.have.lengthOf(1)
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it('throwError: false - should not throw on SQS failure', async() => {
|
|
192
|
+
supCon.throwError = false
|
|
193
|
+
fakeLogger.errors = []
|
|
194
|
+
const response = await supCon.createMessage({ subject: 'Test', text: 'Error' })
|
|
195
|
+
expect(response).to.be.undefined
|
|
196
|
+
expect(fakeLogger.errors).to.have.lengthOf(1)
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
describe('custom logger', () => {
|
|
201
|
+
const originalEnv = process.env.NODE_ENV
|
|
202
|
+
let fakeLogger
|
|
203
|
+
|
|
204
|
+
before(async() => {
|
|
205
|
+
fakeLogger = { infos: [], info(...args) { this.infos.push(args) } }
|
|
206
|
+
await supCon.init({ debug: true, logger: fakeLogger })
|
|
207
|
+
process.env.NODE_ENV = 'production'
|
|
208
|
+
supCon.acsqs = {
|
|
209
|
+
async sendSQSMessage() { return { MessageId: 'abc123' } }
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
after(() => {
|
|
214
|
+
process.env.NODE_ENV = originalEnv
|
|
215
|
+
delete supCon.acsqs
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('logger.info is called on successful send in debug mode', async() => {
|
|
219
|
+
const response = await supCon.createMessage({ subject: 'Test', text: 'Hello' })
|
|
220
|
+
expect(response).to.deep.equal({ MessageId: 'abc123' })
|
|
221
|
+
expect(fakeLogger.infos).to.have.lengthOf(1)
|
|
222
|
+
})
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
describe('logger normalization', () => {
|
|
227
|
+
const originalEnv = process.env.NODE_ENV
|
|
228
|
+
|
|
229
|
+
before(() => {
|
|
230
|
+
process.env.NODE_ENV = 'production'
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
after(() => {
|
|
234
|
+
process.env.NODE_ENV = originalEnv
|
|
235
|
+
delete supCon.acsqs
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
it('null logger - falls back to console without throwing', async() => {
|
|
239
|
+
await supCon.init({ debug: true, logger: null })
|
|
240
|
+
supCon.acsqs = { async sendSQSMessage() { throw new Error('boom') } }
|
|
241
|
+
supCon.throwError = false
|
|
242
|
+
// must not throw a TypeError about this.logger.error
|
|
243
|
+
await supCon.createMessage({ subject: 'Test', text: 'Hello' })
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it('partial logger (missing warn/error) - fills gaps without throwing', async() => {
|
|
247
|
+
const partial = { infos: [], info(...args) { this.infos.push(args) } }
|
|
248
|
+
await supCon.init({ debug: true, logger: partial })
|
|
249
|
+
supCon.acsqs = { async sendSQSMessage() { throw new Error('boom') } }
|
|
250
|
+
supCon.throwError = false
|
|
251
|
+
// error method is missing on partial — must not throw a TypeError
|
|
252
|
+
await supCon.createMessage({ subject: 'Test', text: 'Hello' })
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('partial logger (missing info) - successful send does not throw', async() => {
|
|
256
|
+
const partial = { errors: [], error(...args) { this.errors.push(args) } }
|
|
257
|
+
await supCon.init({ debug: true, logger: partial })
|
|
258
|
+
supCon.acsqs = { async sendSQSMessage() { return { MessageId: 'xyz' } } }
|
|
259
|
+
// info method is missing — must not throw a TypeError on success path
|
|
260
|
+
const response = await supCon.createMessage({ subject: 'Test', text: 'Hello' })
|
|
261
|
+
expect(response).to.deep.equal({ MessageId: 'xyz' })
|
|
262
|
+
})
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
|
|
156
266
|
describe('Cleanup', () => {
|
|
157
267
|
it('Close Redis', async() => {
|
|
158
268
|
redisInstance.quit()
|