recently my node.js server has been crashing a lot due to this socket.io error. My suspicion is that client is sending invalid utf string, which will throw an error in the utf8.js file. Is there a way to avoid server crash? It's very frustrating. I'm down to monkey patch this file if needed.
Error: Lone surrogate U+D83D is not a scalar value
at Error (native)
at checkScalarValue (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js:69:10)
at encodeCodePoint (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js:90:4)
at Object.utf8encode [as encode] (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js:111:18)
at Object.exports.encodePacket (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js:74:34)
at encodeOne (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js:387:13)
at eachWithIndex (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js:256:5)
at map (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js:263:5)
at Object.exports.encodePayloadAsBinary (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js:411:3)
at Object.exports.encodePayload (/root/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js:225:20)
at XHR.Polling.send (/root/node_modules/socket.io/node_modules/engine.io/lib/transports/polling.js:238:10)
at Socket.flush (/root/node_modules/socket.io/node_modules/engine.io/lib/socket.js:341:20)
at Socket.sendPacket (/root/node_modules/socket.io/node_modules/engine.io/lib/socket.js:317:10)
at Socket.send.Socket.write (/root/node_modules/socket.io/node_modules/engine.io/lib/socket.js:290:8)
at writeToEngine (/root/node_modules/socket.io/lib/client.js:148:17)
at Client.packet (/root/node_modules/socket.io/lib/client.js:159:7)
Probably you are trying to send your data in some wrong way.
You could try to have a try {} catch (e) {} around your Client/socket.packet, or do something like this:
process.on('uncaughtException', (err) => {
console.log(`Caught exception: ${err}`);
});
To prevent the server from dieing.
Related
Prevent server from crashing.
I am testing an API with Postman where I am expecting a number with or without decimal places.
But it happens that at the time of testing if I enter a sign like this in Postman: " ) " the server crashes automatically and it seems that it does not reach my validator.
Postman:
{
"concept": "Text",
"incomeAmount": 1)0000,
"expenseAmount": 89,
"description":"Text"
}
Failed response:
SyntaxError: Unexpected token ) in JSON at position 73
at JSON.parse ()
at parse (C:\project\node_modules\body-parser\lib\types\json.js:89:19)
at C:\project\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (C:\project\node_modules\raw-body\index.js:224:16)
at done (C:\project\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (C:\project\node_modules\raw-body\index.js:273:7)
at IncomingMessage.emit (node:events:402:35)
at IncomingMessage.emit (node:domain:475:12)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
I am using express validator like this:
router.post('/new-income',
[
check('incomeAmount', 'El Monto del Ingreso debe ser NĂºmerico').isNumeric().not().isEmpty(),
check('expenseAmount', 'El Monto del Egreso debe ser NĂºmerico').isNumeric().optional({ checkFalsy: true }),
],
validation,
newItem
);
And in the controller, I use Regex to verify that it is a positive number without symbols, but apparently neither the request nor the route arrives.
const regAmount = new RegExp('^[+]?([1-9][0-9]*(?:[\.][0-9]*)?|0*\.0*[1-9][0-9]*)(?:[eE][+-][0-9]+)?$');
if (!regAmount.test(incomeAmount)) {
return res.json ( {
'msg': 'Only positive numbers without signs are allowed'
} );
}
Thanks for your help!
With this much information I can only assume that you are using some kind of json middleware that parse the incoming data.
Unfortunately, the data you sent via postman is not in a valid json format. Ironically enough, only valid number are accepted as value without the need of quotation mark (excluding array and object).
A solution maybe to send the data as pure text to your api and then run in through your validation before converting it into a number.
You can verify the json format yourself here: https://jsonformatter.curiousconcept.com/
This is expected. You're sending illegal JSON so your JSON parsing middleware gets an exception. To catch/handle this error, you need to either install custom middleware that catches the error in the middleware or catch the error from the existing JSON parser in the Express error handler by installing your own Express error handler.
Also, if you're using the express.json() middleware, it has a verify callback option that you can pre-check the JSON if you want, but frankly, it's probably easier to just have an Express error handler and get the error there.
var zapClient = require('zaproxy');
const zapOptions = {
key : 'abcdefghijklmn',
proxy : 'http://localhost:8090/'
};
const zaproxy = new zapClient(zapOptions);
zaproxy.spider.scan("https://www.google.co.in");
i am trying to run above code i am getting :
(node:8380) UnhandledPromiseRejectionWarning: RequestError: Error: socket hang up error.
i have tried socket hang up error with nodejs and "Request error: Socket hang up" with nodeJS on Amazon EC2 didn't help.
I believe changing the last line of your code to this should fix the problem:
zaproxy.spider.scan("https://www.google.co.in", (err, res) => {
if (err) throw err;
//do something with res here
});
//can't do anything with res here
Also check the zap.log file - that might be logging errors which by default are not reported to the client (for security reasons - this can be disabled for testing)
I'm trying to make a HTTPS request-promise. I already know that the PFX is good and that is not the issue (I have a similar sample app working).
I am doing the following:
var request = require('request-promise');
...
options.pfx = fs.readFileSync('myfile.pfx');
options.passphrase = 'passphrase';
I am passing my options into an request.
request.post(options);
I then try to build the request I get the following error:
_tls_common.js:130
c.context.loadPKCS12(pfx, passphrase);
^
Error: Unable to load BIO
at Error (native)
at Object.createSecureContext (_tls_common.js:130:17)
at Object.exports.connect (_tls_wrap.js:955:21)
at Agent.createConnection (https.js:73:22)
at Agent.createSocket (_http_agent.js:174:16)
at Agent.addRequest (_http_agent.js:143:23)
at new ClientRequest (_http_client.js:133:16)
at Object.exports.request (http.js:31:10)
at Object.exports.request (https.js:163:15)
at Request.start (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:747:30)
at Request.write (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:1369:10)
at end (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:561:16)
at Immediate._onImmediate (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:589:7)
at processImmediate [as _immediateCallback] (timers.js:374:17)
I have a sample app where the same code works.
I've tried to convert to .p12 without success.
Does anyone have an idea what this error might refer to?
Edit:
I'm using lodash to do a merge of 2 objects with dinamic properties and static properties
_.merge(options, _this.requestOptions);
And that was causing the problem
Looking at the nodejs source code (specifically this file https://github.com/nodejs/node/blob/master/src/node_crypto.cc)
the error is thrown by this function
// Takes .pfx or .p12 and password in string or buffer format
void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
...
In line 964
in = LoadBIO(env, args[0]);
if (in == nullptr) {
return env->ThrowError("Unable to load BIO");
}
Where the LoadBIO returns null
// Takes a string or buffer and loads it into a BIO.
// Caller responsible for BIO_free_all-ing the returned object.
static BIO* LoadBIO(Environment* env, Local<Value> v) {
HandleScope scope(env->isolate());
if (v->IsString()) {
const node::Utf8Value s(env->isolate(), v);
return NodeBIO::NewFixed(*s, s.length());
}
if (Buffer::HasInstance(v)) {
return NodeBIO::NewFixed(Buffer::Data(v), Buffer::Length(v));
}
return nullptr;
}
Perhaps the buffer is somehow not readable? Also it seems that the function is expecting an utf-8 encoded string.
Some ideas:
Are you sure the path to the file is correct?
Maybe encoding issue? Did you try to set fs.readFileSync() encoding explicitly?
Try with fs.readFile(<filename>, <encoding>, function(error, data){}) to see if it throws an error?
I am using node.js library called urllib (https://github.com/node-modules/urllib) to make http requests. But when I try to run the code I am getting below error:
Error: Hostname/IP doesn't match certificate's altnames
at SecurePair.<anonymous> (tls.js:1379:23)
at SecurePair.EventEmitter.emit (events.js:92:17)
at SecurePair.maybeInitFinished (tls.js:982:10)
at CleartextStream.read [as _read] (tls.js:469:13)
After my research, I found out that I need to add an option called rejectUnauthorized:false. So I added same using below code:
urllib.request(urlToCall, { rejectUnauthorized:false }, function (err, data, response) {
if(err) {
throw err;
}
});
But still I get the same error. Can anyone please guide me how to resolve this error? Since I am beginner to node and this error looks very strange to me, by the way I am using Ubuntu 12.0.4 LTS OS.
So, I have a node server, running expressjs io (uses socket.io), and I'm building a grid map that tracks coordinates in a database.
Only, I've run into a peculiar issue in that my sockets only listen sometimes.
At first there was no error message, and only by chance I let the page run and I got this error.
Uncaught TypeError: Cannot call method '0' of undefined UkPS99A_w96Ae0K570Nt?t=1395276358213&i=0:1
When I click on the file UkPS99A_w96Ae0K570Nt?t=1395276358213&i=0:1 I get this code:
io.j[0]("8::");
If I refresh the page, every few times it will suddenly work find for about 10 tile clicks, and then it stops working. My database is updating properly until the sockets basically die out.
Here is where I send the coordinates in my map:
io.emit("move", {x:this.x,y:this.y});
Server listening:
app.io.route('move', function(req) {
con.getConnection(function(err){
if (err) console.log("Get Connection Error.. "+err);
//removed query because redundant
req.io.emit("talk", {x:req.data.x,y:req.data.y});
});
});
and my socket script:
io.on("talk",function(data) {
console.log(data.x,data.y);
});
My script includes are at the bottom of the page in this order:
<script src="socket.io/socket.io.js"></script>
<script>io = io.connect();</script> <!-- open the socket so the other scripts can use it -->
<script src="../js/sock.js"></script>
<script src="../js/map.js"></script>
Is there something I'm doing wrong to that the socket seems to lose connection and throw some sort of error?
Update: I left the server running longer and a couple more error messages popped up in my console:
Uncaught TypeError: Cannot call method 'close' of null socket.io.js:1967
Uncaught TypeError: Cannot call method 'close' of null socket.io.js:1967
Uncaught TypeError: Cannot call method 'onClose' of null
More update: altered the connection line and added the proper CORS to my server.js
io = io.connect('http://sourceundead.com', {resource : 'socket.io'});
Still the same issue.
You seem to have a connection attrition as you never release them to the pool.
Assuming con is the (bad) name of your pool, instead of
app.io.route('move', function(req) {
con.getConnection(function(err){
if (err) console.log("Get Connection Error.. "+err);
//removed query because redundant
req.io.emit("talk", {x:req.data.x,y:req.data.y});
});
});
you should have something like
app.io.route('move', function(req) {
con.getConnection(function(err, connection){
if (err) console.log("Get Connection Error.. "+err);
//removed query because redundant
req.io.emit("talk", {x:req.data.x,y:req.data.y});
connection.release();
});
});
Be careful that using connections must be done with care to ensure they're always released, and it's a little tedious to do especially when handling errors as soon as you have a few queries to do when doing a task.
At some point you might want to use promises to make that easier. Here's a blog post about using bound promises to ease database querying in node.js.