You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi! I'm using gelf-pro as a tool to send my app's logs through UDP. Recently I started to get ERR_SOCKET_DGRAM_NOT_RUNNING exception from time to time.
Here's an error trace:
Error [ERR_SOCKET_DGRAM_NOT_RUNNING]: Not running
at new NodeError (node:internal/errors:363:5)
at healthCheck (node:dgram:908:11)
at Socket.close (node:dgram:740:3)
at cbResults (path/to/my/app/node_modules/gelf-pro/lib/adapter/udp.js:75:14)
at /path/to/my/app/node_modules/gelf-pro/lib/adapter/udp.js:118:13
at processTicksAndRejections (node:internal/process/task_queues:83:21)
As specified in the stack trace - the error happens when Socket.close is called.
After investigation I found that this happens only when request body is more than 1388 bytes and gelf-pro divides body in chunks.
The bug is in this code(from /lib/adapter/udp.js:103):
for (var idx in chunks) {
if (isInterrupted) {
break;
}
var chunk = chunks[idx],
packet = buffer
.from(self.specification.magicBytes.concat(packetId, idx, chunksCount, chunk));
client.send(
packet, 0, packet.length, self.options.port, self.options.host,
function (err, bytesSent) {
if (err) { return cbResults(err); }
bytesSentTotal += bytesSent;
/* istanbul ignore else */
if (idx >= chunksCount - 1) {
cbResults(err, bytesSentTotal);
}
}
);
}
More specifically in this closure:
if (idx >= chunksCount - 1) {
cbResults(err, bytesSentTotal);
}
Here idx is specified to check whether we arrived at the end of chunks array or not, but because of how JavaScript variable scope works what actually happens is - idx is always equal to chunksCount - 1 and cbResults is called on every loop, not only on the last one (hence ERR_SOCKET_DGRAM_NOT_RUNNING error because we try to close udp connection multiple times). Great example of how and why it works like this is provided here.
So here's a fix I came up with. What's important to note - in order for this fix to work you must use const(or let), not var(because var variable are not scope bound and by using var we actually do the same thing).
diff --git a/node_modules/gelf-pro/lib/adapter/udp.js b/node_modules/gelf-pro/lib/adapter/udp.js
index 58e452d..431b38c 100644
--- a/node_modules/gelf-pro/lib/adapter/udp.js+++ b/node_modules/gelf-pro/lib/adapter/udp.js@@ -101,20 +101,21 @@ adapter.send = function (message, callback) {
var packetId = Array.prototype.slice.call(crypto.randomBytes(8));
for (var idx in chunks) {
+ const capturedIndex = idx;
if (isInterrupted) {
break;
}
var chunk = chunks[idx],
packet = buffer
.from(self.specification.magicBytes.concat(packetId, idx, chunksCount, chunk));
client.send(
packet, 0, packet.length, self.options.port, self.options.host,
function (err, bytesSent) {
if (err) { return cbResults(err); }
bytesSentTotal += bytesSent;
/* istanbul ignore else */
- if (idx >= chunksCount - 1) {+ if (capturedIndex >= chunksCount - 1) {
cbResults(err, bytesSentTotal);
}
}
Hi! I'm using gelf-pro as a tool to send my app's logs through UDP. Recently I started to get ERR_SOCKET_DGRAM_NOT_RUNNING exception from time to time.
Here's an error trace:
As specified in the stack trace - the error happens when Socket.close is called.
After investigation I found that this happens only when request body is more than 1388 bytes and gelf-pro divides body in chunks.
The bug is in this code(from /lib/adapter/udp.js:103):
More specifically in this closure:
Here
idx
is specified to check whether we arrived at the end of chunks array or not, but because of how JavaScript variable scope works what actually happens is - idx is always equal tochunksCount - 1
andcbResults
is called on every loop, not only on the last one (hence ERR_SOCKET_DGRAM_NOT_RUNNING error because we try to close udp connection multiple times). Great example of how and why it works like this is provided here.So here's a fix I came up with. What's important to note - in order for this fix to work you must use const(or let), not var(because var variable are not scope bound and by using var we actually do the same thing).
This issue body was partially generated by patch-package.
The text was updated successfully, but these errors were encountered: