Skip to content

Commit ff9ea3f

Browse files
committed
- fix unhandled error when flushing logs
1 parent c6db556 commit ff9ea3f

File tree

5 files changed

+103
-22
lines changed

5 files changed

+103
-22
lines changed

src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,11 @@ class Backendless {
278278
return this.domain + this.apiURI
279279
}
280280

281-
return [this.serverURL, this.appId, this.apiKey].join('/')
281+
if (this.appId && this.apiKey) {
282+
return [this.serverURL, this.appId, this.apiKey].join('/')
283+
}
284+
285+
return null
282286
}
283287

284288
set appPath(appPath) {

src/logging/index.js

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,20 @@ export default class Logging {
7878

7979
this.messages = []
8080

81-
this.flushRequest = this.app.request
82-
.put({
83-
url : this.app.urls.logging(),
84-
data: messages
85-
})
86-
.catch(error => {
87-
this.messages = [...messages, ...this.messages]
88-
89-
this.checkMessagesLimit()
90-
91-
throw error
81+
this.flushRequest = Promise.resolve()
82+
.then(() => {
83+
return this.app.request
84+
.put({
85+
url : this.app.urls.logging(),
86+
data: messages
87+
})
88+
.catch(error => {
89+
this.messages = [...messages, ...this.messages]
90+
91+
this.checkMessagesLimit()
92+
93+
throw error
94+
})
9295
})
9396
.finally(() => delete this.flushRequest)
9497
}
@@ -116,6 +119,10 @@ export default class Logging {
116119
this.checkMessagesLenTimer = setTimeout(() => {
117120
if (this.messages.length >= this.numOfMessages) {
118121
this.flush()
122+
.catch(error => {
123+
// eslint-disable-next-line no-console
124+
console.error('Could not flush log messages immediately: ', error)
125+
})
119126
} else {
120127
this.startFlushInterval()
121128
}
@@ -130,7 +137,13 @@ export default class Logging {
130137

131138
startFlushInterval() {
132139
if (!this.flushInterval) {
133-
this.flushInterval = setTimeout(() => this.flush(), this.timeFrequency * 1000)
140+
this.flushInterval = setTimeout(() => {
141+
this.flush()
142+
.catch(error => {
143+
// eslint-disable-next-line no-console
144+
console.error('Could not flush log messages with timer: ', error)
145+
})
146+
}, this.timeFrequency * 1000)
134147
}
135148
}
136149

src/urls.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ export default class Urls {
44
}
55

66
root() {
7+
if (!this.app.appPath) {
8+
throw new Error(
9+
'Backendless API is not configured, make sure you run Backendless.initApp(...) ' +
10+
'before the operation'
11+
)
12+
}
13+
714
return this.app.appPath
815
}
916

test/unit/specs/logging.js

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ describe('<Logging>', function() {
213213
})
214214

215215
it('doesnt throw an error if the message is not a string', async () => {
216+
prepareMockRequest({})
217+
216218
async function check(method) {
217219
expect(() => logger[method](0)).to.not.throw()
218220
expect(() => logger[method](123)).to.not.throw()
@@ -231,6 +233,8 @@ describe('<Logging>', function() {
231233
await check('error')
232234
await check('fatal')
233235
await check('trace')
236+
237+
await Backendless.Logging.flush()
234238
})
235239

236240
it('converts non-string values to strings', async () => {
@@ -324,8 +328,16 @@ describe('<Logging>', function() {
324328
})
325329

326330
it('should try to send next time if it was failed', async () => {
331+
// eslint-disable-next-line no-console
332+
const _nativeConsoleError = console.error
333+
334+
// eslint-disable-next-line no-console
335+
const spyConsoleError = console.error = chai.spy()
336+
337+
const error = new Error('Test Error')
338+
327339
const req1 = prepareMockRequest(() => {
328-
throw new Error('Test Error')
340+
throw error
329341
})
330342

331343
const req2 = prepareMockRequest()
@@ -357,14 +369,30 @@ describe('<Logging>', function() {
357369
{ 'log-level': 'DEBUG', 'logger': loggerName, 'message': 'debug message - 2', timestamp: req1.body[1].timestamp },
358370
{ 'log-level': 'DEBUG', 'logger': loggerName, 'message': 'debug message - 3', timestamp: req2.body[2].timestamp }
359371
])
372+
373+
expect(spyConsoleError).to.have.been.called.exactly(1)
374+
375+
expect(spyConsoleError).on.nth(1).be.called.with('Could not flush log messages immediately: ', error)
376+
377+
// eslint-disable-next-line no-console
378+
console.error = _nativeConsoleError
360379
})
361380

362381
it('should keep messages if they were not sent #1', async () => {
382+
// eslint-disable-next-line no-console
383+
const _nativeConsoleError = console.error
384+
385+
// eslint-disable-next-line no-console
386+
const spyConsoleError = console.error = chai.spy()
387+
388+
const error1 = new Error('Test Error1')
389+
const error2 = new Error('Test Error2')
390+
363391
const req1 = prepareMockRequest(() => {
364-
throw new Error('Test Error1')
392+
throw error1
365393
})
366394
const req2 = prepareMockRequest(() => {
367-
throw new Error('Test Error2')
395+
throw error2
368396
})
369397
const req3 = prepareMockRequest()
370398

@@ -406,14 +434,31 @@ describe('<Logging>', function() {
406434
{ 'log-level': 'DEBUG', 'logger': loggerName, 'message': 'debug message - 5', timestamp: req3.body[4].timestamp },
407435
{ 'log-level': 'DEBUG', 'logger': loggerName, 'message': 'debug message - 6', timestamp: req3.body[5].timestamp },
408436
])
437+
438+
expect(spyConsoleError).to.have.been.called.exactly(2)
439+
440+
expect(spyConsoleError).on.nth(1).be.called.with('Could not flush log messages immediately: ', error1)
441+
expect(spyConsoleError).on.nth(2).be.called.with('Could not flush log messages immediately: ', error2)
442+
443+
// eslint-disable-next-line no-console
444+
console.error = _nativeConsoleError
409445
})
410446

411447
it('should keep messages if they were not sent #2', async () => {
448+
// eslint-disable-next-line no-console
449+
const _nativeConsoleError = console.error
450+
451+
// eslint-disable-next-line no-console
452+
const spyConsoleError = console.error = chai.spy()
453+
454+
const error1 = new Error('Test Error1')
455+
const error2 = new Error('Test Error2')
456+
412457
const req1 = prepareMockRequest(() => {
413-
throw new Error('Test Error1')
458+
throw error1
414459
})
415460
const req2 = prepareMockRequest(() => {
416-
throw new Error('Test Error2')
461+
throw error2
417462
})
418463
const req3 = prepareMockRequest()
419464

@@ -461,6 +506,14 @@ describe('<Logging>', function() {
461506
{ 'log-level': 'DEBUG', 'logger': loggerName, 'message': 'debug message - 7', timestamp: req3.body[5].timestamp },
462507
{ 'log-level': 'DEBUG', 'logger': loggerName, 'message': 'debug message - 8', timestamp: req3.body[6].timestamp },
463508
])
509+
510+
expect(spyConsoleError).to.have.been.called.exactly(2)
511+
512+
expect(spyConsoleError).on.nth(1).be.called.with('Could not flush log messages immediately: ', error1)
513+
expect(spyConsoleError).on.nth(2).be.called.with('Could not flush log messages immediately: ', error2)
514+
515+
// eslint-disable-next-line no-console
516+
console.error = _nativeConsoleError
464517
})
465518

466519
it('should send 100 messages by default', async () => {

test/unit/specs/rt/basic.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,17 @@ describe('<RT> Basic', function() {
201201
const rtAppId = 'rt-app-id'
202202
const rtAPIKey = 'rt-api-key'
203203

204-
const backendlessApp = Backendless.initApp({
205-
domain,
206-
standalone: true,
207-
})
204+
let backendlessApp
208205

209206
before(async () => {
210207
rtClient = await createMockRTServer(rtAppId)
208+
})
209+
210+
beforeEach(async () => {
211+
backendlessApp = Backendless.initApp({
212+
domain,
213+
standalone: true,
214+
})
211215

212216
backendlessApp.appInfoPromise = chai.spy(() =>
213217
Promise.resolve({ appId: rtAppId, apiKey: rtAPIKey, rtURL: host })

0 commit comments

Comments
 (0)