-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Added error handling to imcomingStore.put callback in _handlePublish. #864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Added asynchronous result callback function and error handling in _handlePubrel similar to _handlePublish.
Store is a interface. https://github.com/redboltz/MQTT.js/blob/master/lib/store.js always completes writing when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will need unit tests.
@@ -1082,12 +1085,16 @@ MqttClient.prototype._handlePubrel = function (packet, callback) { | |||
that.incomingStore.get(packet, function (err, pub) { | |||
if (!err && pub.cmd !== 'pubrel') { | |||
that.emit('message', pub.topic, pub.payload, pub) | |||
that.incomingStore.put(packet) | |||
that.handleMessage(pub, function (err) { | |||
that.incomingStore.put(packet, function (err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if we called handleMessage
before sending a PUBCOMP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The updated code calls handleMessage
before sending a PUBCOMP. The sequence is not changed before/after update.
lib/client.js
Outdated
this.incomingStore.put(packet, function () { | ||
this.incomingStore.put(packet, function (err) { | ||
if (err) { | ||
return done && done(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can done be null? If that is true, than can you please assign it to a noop function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure but the existing code https://github.com/mqttjs/MQTT.js/blob/master/lib/client.js#L974 cheking it. So I applied the same manner.
I've checked call sequence.
handlePublish
is called only from https://github.com/mqttjs/MQTT.js/blob/master/lib/client.js#L336 in handlePacket
. And handlePacket
is called only from https://github.com/mqttjs/MQTT.js/blob/master/lib/client.js#L292.
At that point, nextTickWork
is passed as the 2nd parameter, callback.
nextTickWork
is defined https://github.com/mqttjs/MQTT.js/blob/master/lib/client.js#L283. It cannot be null.
So null checking is not required. I will remove it from my update and existing code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed done &&
on my environment.
Then I got errors on the following test:
https://github.com/mqttjs/MQTT.js/blob/master/test/abstract_client.js#L953
Can I remove the test?
Or revert as follows?
return done && done(err)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or
MqttClient.prototype._handlePublish = function (packet, done = function (){}) {
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I choose
MqttClient.prototype._handlePublish = function (packet, done = function (){}) {
Because
- Someone might depend on existing test. So I shouldn't remove it.
- You mentioned using empty function is better for empty callback at Added error handling to imcomingStore.put callback in _handlePublish. #864 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To support ES5 and older, I fixed as follows:
MqttClient.prototype._handlePublish = function (packet, done) {
done = typeof done !== 'undefined' ? done : function () {}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a handy nop()
function https://github.com/mqttjs/MQTT.js/blob/master/lib/client.js#L66.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't notice it. I replaced it.
lib/client.js
Outdated
that._sendPacket(comp, callback) | ||
that.handleMessage(pub, function (err) { | ||
if (err) { | ||
return callback && callback(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you please assign an empty function to callback if it's not present and remove the two checks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let me clarify. You mean
that.incomingStore.get(packet, function (err, pub) {
if (!err && pub.cmd !== 'pubrel') {
that.emit('message', pub.topic, pub.payload, pub)
that.incomingStore.put(packet, function (err) {
if (err) {
return callback(err)
}
that.handleMessage(pub, function (err) {
if (err) {
return callback(err)
}
that._sendPacket(comp, callback)
})
})
} else {
that._sendPacket(comp, callback)
}
})
right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I pasted wrong code.
Finally I fixed the code as follows:
MqttClient.prototype._handlePubrel = function (packet, callback) {
callback = typeof callback !== 'undefined' ? callback : function () {}
var mid = packet.messageId
var that = this
var comp = {cmd: 'pubcomp', messageId: mid}
that.incomingStore.get(packet, function (err, pub) {
if (!err && pub.cmd !== 'pubrel') {
that.emit('message', pub.topic, pub.payload, pub)
that.incomingStore.put(packet, function (err) {
if (err) {
return callback(err)
}
that.handleMessage(pub, function (err) {
if (err) {
return callback(err)
}
that._sendPacket(comp, callback)
})
})
} else {
that._sendPacket(comp, callback)
}
})
}
Codecov Report
@@ Coverage Diff @@
## master #864 +/- ##
=========================================
+ Coverage 94.05% 94.1% +0.04%
=========================================
Files 8 8
Lines 757 763 +6
Branches 188 190 +2
=========================================
+ Hits 712 718 +6
Misses 45 45
Continue to review full report at Codecov.
|
It’s not clear what you mean. Can you pass in a custom object to add this test? |
Ok I will add test that contains cutstom Store. |
Added unit test.
Default paramter is introduced since ES6. Replaced the way that supports older ES,
The original code doesn't use AsyncStore such as mqtt-level-store might take a time to complete This test check it. |
test/abstract_client.js
Outdated
AsyncStore.prototype.put = function (packet, cb) { | ||
setTimeout(function () { | ||
cb(new Error('Error')) | ||
}, 200) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you shorten these? A process.nextTick might be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
One travis-ci failed. (nodejs6) https://travis-ci.org/mqttjs/MQTT.js/jobs/422322347#L1785
It seems that it is not related the fix. |
I've checked all tests has been passed on my travis-ci. |
Thank you for merging. |
Added asynchronous result callback function and error handling in
_handlePubrel similar to _handlePublish.