Unable to get request timeout response using node.js - node.js

I am trying to set the timeout values inside request module of node.js but as per the given time its not returning the response. I am explaining my code below.
postRequestOptions.url = `${nsoObj.protocol}://${nsoObj.ipAddress}:${nsoObj.httpPortNbr}/jsonrpc`;
postRequestOptions.headers = {
'Content-Type': 'application/json'
};
postRequestOptions.body = {
jsonrpc: '2.0',
id: 1,
method: 'login',
timeout: 5000,
params: {
user: nsoObj.userName,
passwd: nsoObj.password
}
};
request(postRequestOptions, (error, response, loginResponse) => {
console.log('\n error: ', error);
console.log('\n loginResponse: ', loginResponse);
if (error || !loginResponse.id) {
responseObj = {
status : 'error',
msg : `Error occurred while performing Login into "${nsoObj.nsoNickName}" Instance. ${error}`,
body : null
};
reject(responseObj);
} else {
loginResponse.sessionId = response.headers['set-cookie'][0];
responseObj = {
status : 'success',
msg : `Successfully performing Login into "${nsoObj.nsoNickName}" Instance`,
body : loginResponse
};
resolve(responseObj);
}
});
});
Here I am using request module of node.js and set timeout of 5ms. But When I am running this its taking 2min to sent back the timeout error response.
Here I need if this request could not sent back the response within 5 milisecond then it should return the timeout error.

delete timeout from body and using postRequestOptions.timeout = 5000; so do like this:
postRequestOptions.url = `${nsoObj.protocol}://${nsoObj.ipAddress}:${nsoObj.httpPortNbr}/jsonrpc`;
postRequestOptions.headers = {
'Content-Type': 'application/json'
};
postRequestOptions.body = {
jsonrpc: '2.0',
id: 1,
method: 'login',
params: {
user: nsoObj.userName,
passwd: nsoObj.password
}
};
postRequestOptions.timeout = 5000;//should be outside the body
request(postRequestOptions, (error, response, loginResponse) => {
console.log('\n error: ', error);
console.log('\n loginResponse: ', loginResponse);
if (error || !loginResponse.id) {
responseObj = {
status : 'error',
msg : `Error occurred while performing Login into "${nsoObj.nsoNickName}" Instance. ${error}`,
body : null
};
reject(responseObj);
} else {
loginResponse.sessionId = response.headers['set-cookie'][0];
responseObj = {
status : 'success',
msg : `Successfully performing Login into "${nsoObj.nsoNickName}" Instance`,
body : loginResponse
};
resolve(responseObj);
}
});
});

Related

React Expo: FileSystem.uploadAsync not sending request to the server instead throwing error

I am developing an app on react expo, and using Filesystem.uploadasync for file uploading and other data. But filesystem is not sending request to the server and throwing error "
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_context.t0.response.data')]". Below is my code
const addRequest = async (values, url) => {
try {
const user = await getData('user');
if (user != null) {
const token = user.Token;
const requestBody = {Branches: values.Branches, Color: values.Color, ImageInPOS: values.ImageInPOS, Name: values.Name, VisibilityInPOS: values.ImageInPOS}
console.log(requestBody);
console.log(values.Image.uri);
const result = await FileSystem.uploadAsync(`${BaseUrl}/${url}`, values.Image.uri, {
fieldName: 'Image',
httpMethod: "POST",
uploadType: FileSystemUploadType.MULTIPART,
parameters: requestBody,
headers: {
authorization: `Bearer ${token}`,
}
})
console.log(result);
return {
msg: result.data.msg,
status: result.status
};
}
else {
return;
}
}
catch (err) {
return {
msg: err.response.data.msg ? err.response.data.msg : "Something went wrong, Try Again",
status: err.response.status ? err.response.status : 500
};
}
}
I have cross checked my url, all imports but could not figure out what is going wrong.

API response from inomnia is different than the error (from yup validator) on client side

So I am using yup validator
beeraverage: yup.number("Not a number").min(0).nullable(true),
testing with "beeraverage": "4.5.9", in the object. Then I get this with insomnia:
As expected.
Using this code to catch up the yup error:
.catch(yupError => {
const errors = yupError.inner.reduce((acc, error) => {
const { path, message } = error;
if (!acc.hasOwnProperty(path)) {
acc[path] = [message];
}
else {
acc[path].push(message);
}
return acc;
}, {});
res.status(errorCode).json(new InvalidFieldErrorResponse(
'Data invalid',
errors,
errorCode
));
});
(Btw how can I get the error "Not a number" written in the code above in the validator ???)
and then when I try in the client side using axios :
axios.put('http://10.0.2.2:8080/api/bar/' + id, changes, { headers: { "Authorization": `Bearer ${token}` } })
.then(function (response) {
console.log("reponse update bar: " + JSON.stringify(response.data.result, null, 4));
setResponse(response.data.result);
})
.catch(function (error) {
console.log("error update bar: " + JSON.stringify(error, null, 4));
setError(error.message);
})
.finally(function () {
setLoading(false);
});
I get an error completely different and nothing to do with it :
How can I get the errors from yup in the client side please ?
So because axios encapsulate it, the error call that you get in insomnia/postman is:
error.response.data
and map on error.response.data.fieldErrors
And for the custom error message:
beeraverage: yup.number().typeError("Not a number").min(0).nullable(true),
and to get the fields errors:
axios.put('http://10.0.2.2:8080/api/bar/' + id, changes, { headers: { "Authorization": `Bearer ${token}` } })
.then(function (response) {
//console.log("reponse update : " + JSON.stringify(response.data.result, null, 4));
setResponse(response.data.result);
})
.catch(function (error) {
var errors = "";
for (const fields in error.response.data.fieldErrors) {
console.log("fields: " + JSON.stringify(fields, null, 4))
error.response.data.fieldErrors[fields].map(item => (
errors = errors.concat("\n" + item)
))
}
setError(errors);
})
.finally(function () {
setLoading(false);
});

Return status in Nodejs caused Network request failed

This is a newbie question about return in Nodejs (10.16) and express (4.16.4), front end is react native 0.59. Here is the code on Nodejs server returning a status 200 after successful query:
router.post('/new', [auth_deviceid, auth_userinfo, auth_role(['admin', 'eventer', 'messager'])], async (req, res) => {
//prepare obj msg....
try {
await msg.save();
msg.user_name = req.body.alias;
msg.user_avatar = req.user.user_data.avatar;
const io = req.app.get("io");
const socket_id = req.body.socket_id;
const socket = io.sockets.connected[socket_id];
const room = msg.event_id.toString();
socket.join(room);
socket.to(room).emit("event message", msg);
console.log("after emit to room : ", room); //<<<==this line shown in console screen
return res.status(200); //<<<=== hang here with no error thrown. But instead res.status(200).send("I am ok") is working.
} catch (err) {
console.log("Error in saving/braodcasting a new message", err);
return res.status(400).send(err.message);
};
});
The above code is called in react native with the code below:
async _onSend(messages = []) {
//do something...
let obj = JSON.stringify({
_device_id: DeviceInfo.getUniqueID(),
sender_id: this.state.myself.id,
sender_grpmember_id:(this.props.grpmember_id || this.props.navigation.state.params.grpmember_id),
alias:this.props.alias,
socket_id: this.props.socket.id,
data: {
msg_body:messages[0].text,
upload_content_info: ""
},
event_id: this.props.navigation.state.params.eventId,
_grpmember_id:(this.props.grpmember_id || this.props.navigation.state.params.grpmember_id),
_group_id:(this.props.group_id || this.props.navigation.state.params.group_id),
});
try {
let url = `${GLOBAL.BASE_URL}/api/messages/new`;
console.log("Chat message URL : ", obj);
let res = await fetch(url, {
method: "POST",
headers: {
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json',
"x-auth-token": result.password,
"x-auth-secret" : result.username,
},
body: obj,
});
}
catch (err) {
console.log("Error in saving message : ", err);
};
}
On console screen, received the error below:
09-25 17:19:20.325 15181 15252 I ReactNativeJS: 'Chat message URL : ', '{"_device_id":"0cfce7b7e86fa397","sender_id":1,"sender_grpmember_id":1,"alias":"jc","socket_id":"z-8JjwQvKo6ed57KAAAB","data":{"msg_body":"hello","upload_content_info":""},"event_id":1,"_grpmember_id":1,"_group_id":"1"}'
09-25 17:19:20.345 15181 15252 I ReactNativeJS: In GiftedChat render :
09-25 17:20:35.554 15181 15252 I ReactNativeJS: 'Error in saving message : ', { [TypeError: Network request failed]
09-25 17:20:35.554 15181 15252 I ReactNativeJS: line: 24115,
09-25 17:20:35.554 15181 15252 I ReactNativeJS: column: 31,
09-25 17:20:35.554 15181 15252 I ReactNativeJS: sourceURL: 'http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false' }
Why the return res.status(200) is causing the error of Network request failed?
Your request takes about 15s, as you point, return res.status(200); just only set http status code for the response, to finish a request you would use res.json, res.send or res.end.
In this case, I think you only need send a success with http status code is 200,
You could use res.sendStatus(200); (res.sendStatus is shorthand for implementing res.status and res.send) instead of res.status(200).

Firebase cloud function http sending push notification to device successfully but it falls into the catch block with empty error

Firebase cloud function HTTP send a push notification to device,
notification is sending successfully but it falls into the catch
block with an empty error instead of response block
here's my index.js code:
exports.test = functions.https.onRequest((request, response) => {
var missingData = [];
var tokenPass = request.query.token_passed ? request.query.token_passed : missingData.push({
key : 'token',
message : "Token cannot be null"
});
if (missingData.length > 0) {
response.status(403);
responseData = {
status : 403,
success : false,
message : "Missing data input",
data : missingData
}
response.send(responseData);
return;
}
const payload = {
notification: {
title: 'Hi',
body: 'Body'
}
};
// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().sendToDevice(tokenPass, payload)
.then((response) => {
response.status(200);
response.send({
status : 200,
success : true,
message : "send notification successful"
});
return;
})
.catch((error) => {
response.status(500);
response.send({
status : 500,
success : false,
err: error,
message : "internal error"
});
return;
});
});
Here's the response which I get:
{
"status": 500,
"success": false,
"err": {},
"message": "internal error"
}
I tried doing like this too, but no success:
var message = {
notification: {
title: titlePass,
body: bodyPass
},
token: tokenPass
};
// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().send(message)
P.S. I added the stripe module to my firebase functions, could it be causing issues?

Google nocaptcha post from server to siteverify says details are missing

[ { hostname: 'www.google.com',
path: '/recaptcha/api/siteverify',
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Content-Length': 556 } },
'{"secret":"XXXUseThisForCommunicationBetweenYourSiteAndGoogleXXX","response":"03AHJ_VuusXdr5IdGpNzQPRjedGs-Le066Fx9r-Lk1gIfLqlzwxapPx70_LukmcOsw3x-m2DSfpvQVylx060H9IjFP82fy7505_t_rjSivauiwBUyQPrBMp5kTRviq_DD1L2mVMTTrBieUMlQM69AIuG3KwmdOQMyMJS2iJdRuRNnvAmDlPSejkASR4X-7c4IIP3NoMb52Qsl9QPeU6kGaPtxqmf1IpNwbSC3bzLXQD-QV1aI4GgaeqSPfOO8EPfISJMQ5kbCd9wqAwHqDAXMtNSvz10Ty30R71HqmsSk7YHddFQhei1L6y9j7nxnY5QtAxHehhpYwJVNjI96hxeIaG58_CQHGbAufy4aPGAlf-zJ6be_Xtdzd4AnHxiX9OuCKQI8eQlh6DZLGaymxXDmPNu4TijGyyu0VeTPTTKf12zVUg86_0ZmszWZDtALjnNnxBH7bZqrgWXhy","remoteip":"00.00.000.000"}' ]
If I post that and google returns this:
{ success: false, 'error-codes': [ 'missing-input-response', 'missing-input-secret'] }
I don't see what is happening wrong
https://www.google.com/recaptcha/admin#site/XXXXXX?setup says:
When your users submit the form where you integrated reCAPTCHA, you'll get as part of the payload a string with the name "g-recaptcha-response". In order to check whether Google has verified that user, send a POST request with these parameters:
URL: https://www.google.com/recaptcha/api/siteverify
secret(required) - XXXXXX,
response(required) - The value of 'g-recaptcha-response',
remoteip - The end user's ip address.
I have clearly sent all these things! What could be happening here? The error does not say they are wrong, it says they are 'missing'
And the above Quoted text from google clearly says POST not GET Google reCAPTCHA: how to get user response and validate in the server side
But if I try a GET request then the response is [ null, 400, undefined ]
UPDATE
As #mscdex pointed out application/x-www-form-urlencoded is required but the responce still said that it was missing the secret so I url encoded this instead as I figured something bad may be happening to the item at the start of the object.
{'_':'_','secret':'XXXXXX','response':'whateverXXYsgTSG','remoteip':'00.00.000.000'}
And finally it worked:
[ { hostname: 'www.google.com',
path: '/recaptcha/api/siteverify?',
method: 'POST',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 548 } },
'"_=_&secret=XXXXXX&response=03AHJ_VuurQFgsftybLlvrdGOwXfNneWp4v7FPJJbOD9CGpiHAkFBaiNy7YWXcHrAkU6SPU5UZpgKCptU3gRX5OPqXEh2qqP3nXJpiBWoxFW_Iv05P2UA23rzzZk0ecScmMSL1PP1uyBCdJ08HpAWEuz2PzL6m6u71k09xQbVbPZ5KT6qnb-mdPNyEkdBxtc9a5oYpnOoHg7ax6q4Ms4Lis4qrNBLCavKmYZ6vAmYitSEI0a0GERnlI3wLSvayhc-Yygv1koKIjg2q8GHXV1UhKLzBa8t8x2ibRBNwXUMBFs3Qj_lfwgiTNtIaU3kEAFPULJulZDOsAcovKpjk5xkyMM2C5YDGYMioeyOMl9ZmyyvkwfrrRe8e9o_tD6SaTTSAcrcxsfYGm-w0_CDbsa2IWSkjiMN-2B9SClOZJGXXVXVIuIYClIK3XuUvTsObCzxJAq2IKwwMTtYX&remoteip=00.00.000.000"' ]
[ { success: true }, 200, undefined ]
But I would like to do this properly not hacky So if anyone can answer how to do it properly that would be swell!
var JSON={
https:require('https')
, toquery:require('../node_modules/querystring').stringify
, stringify:require('../node_modules/json-stringify-safe')
, parse:require('../node_modules/try-json-parse')
, get:function(url,callback){process.env.NODE_TLS_REJECT_UNAUTHORIZED="0";var req=JSON.https.request(url,function(res){var buffer='';res.setEncoding('utf8');res.on('data',function(chunk){buffer+=chunk;});res.on('end',function(){try{var data=JSON.parse(buffer);callback(data,res.statusCode);}catch(e){console.log(e);}});});req.end();}
, post:function(url,path,data,type,callback){if(!callback){callback=type;type=undefined;}data=JSON.stringify(data);var options={hostname:url,path:path,method:'POST',headers:{'Content-Type':type||'application/json','Content-Length':data.length}};console.dir([options,data]);var req=JSON.https.request(options,function(res){var buffer='';res.setEncoding('utf8');res.on('data',function(chunk){buffer+=chunk;});res.on('end',function(){try{var data=JSON.parse(buffer);callback(data,res.statusCode);}catch(e){console.log(e);}});});req.write(data);req.end();}
};
JSON.post(
'www.google.com'
, '/recaptcha/api/siteverify?'
, JSON.toquery({'_':'_','secret':'XXXX','response':response,'remoteip':remoteip})
, 'application/x-www-form-urlencoded'
, function(data,result,statusCode){
console.dir([data,result,statusCode]);
if(result.success){}
else{}
});
Here is how I do it in one of my project using superagent. This is my recaptcha-helper.js
var request = require("superagent");
var config = {
recaptcha: {
secret: "XXXXX",
url: "https://www.google.com/recaptcha/api/siteverify",
},
};
var ERROR_CODES = {
"missing-input-secret": "Unexpected Server Error (1)",
"invalid-input-secret": "Unexpected Server Error (2)",
"missing-input-response": "Missing reCAPTCHA value",
"invalid-input-response": "Invalid reCATPCHA value",
};
exports.getErrorCode = function (errorCode) {
if (Array.isArray(errorCode)) {
var errors = errorCode.map(function (code) {
return exports.getErrorCode(code);
});
return errors.join("\n");
}
return ERROR_CODES[errorCode] ||
(errorCode ? ("Unexpected reCAPTCHA error: " + errorCode) : "Unexpected reCAPTCHA error");
};
exports.parseResponse = function (err, res) {
if (err) {
return { success: false, error: err };
} else if (!res.body.success) {
var error = new Error(exports.getErrorCode(res.body["error-codes"]));
return { success: false, error: error };
} else {
return { success: true };
}
};
exports.verify = function (response, ip) {
if (process.env.NODE_ENV === "test") {
return response ? Promise.resolve() :
Promise.reject(new Error("Test reCAPTCHA Error"));
}
return new Promise (function (resolve, reject) {
request.post(config.recaptcha.url)
.type("form")
.accept("json")
.send({
secret: config.recaptcha.secret,
response: response,
remoteip: ip,
})
.end(function (err, res) {
var parsedRes = exports.parseResponse(err, res);
return parsedRes.success ? resolve() : reject(parsedRes.error);
});
});
};
And you can use it doing
var captchaHelper = require('./recaptcha-helper');
captchaHelper.verify(req.body.captcha, req.ip)
.then(function () {
// on success
}).catch(function (err {
// on error
});
I solved this by passing secret and response as a query parameter:
Example :
axios.post("https://www.google.com/recaptcha/api/siteverify?secret="
+ 'XXXXXX' + "&response=" + response + "&remoteip=" + req.connection.remoteAddress);

Resources