Postman aways identify 200 on Nodejs + Express even when i send other - node.js

I'm using API coded in NodeJS but always Postman identify HttpStatus 200, even when i send 4XX or other.
I'm using express and body-parser
As you can see below:
The code is:
router.get('/', async(req, res) => {
try{
let dados = await busca(0);
let pasta = '/upload/'
let nomearquivo = '';
var contents = '';
if (dados){
for (const [idx,row] of dados.entries()){
nomearquivo = pasta + row.arquivotitulo;
if (fs.existsSync(nomearquivo)){
contents = fs.readFileSync(nomearquivo, {encoding:'base64'});
dados[idx]['arquivotitulo64'] = contents;
}
}
return res.status(200).send(dados);
}else{
return res.sendStatus(404);
}
}catch (err){
console.log(err);
return res.sendStatus(500);
}
});
Can anyone help me to send correctly resposes that turns possible to identify in Postman the correct Status code?

Try like this res.status(404).send('Not Found'); It should work and straightforwrd

Related

How to return database data from NodeJS Express routes?

Working with NodeJS for the first time, trying to build a public endpoint that an accept an XML file, convert it to JSON, save it to MongoDB, then send a 200 HTTP status code, if everything went well. But the Express route completes and sends a response long before the code writing to the database completes.
A slightly simplified version:
app.post('/ams', function (req, res) {
try {
if (Object.keys(req.body).length === 0) {
console.log("request body was empty");
// throw new EmptyBodyException(req.body);
message = message + "Request body was empty \n";
}
let body_keys = Object.keys(req.body);
let body_values = Object.values(req.body);
let xml_string = body_keys[0] + ":" + body_values[0];
let xml = xml_string.trim();
console.log("The trimmed XML:");
console.log(xml);
// convert XML to JSON
xml2js.parseString(xml, (err, json) => {
if(err) {
message = "xml2js.parseString failed, xml was:." + xml + "\n\n" + err;
console.log(message);
res.status(500);
res.send(message);
}
const documentType = json.Document.DocumentType;
if (documentType == 945) {
const shipment = json.Document.Shipment[0];
const shipment_header = shipment.ShipmentHeader[0];
const addresses = shipment.Addresses[0].Address;
const order_header = shipment.Orders[0].Order[0].OrderHeader[0];
const cartons = shipment.Orders[0].Order[0].Cartons[0].Carton;
const unique_id = shipment_header.ShipmentID[0];
found_document_promise = document_is_redundant(AMS_945, unique_id);
found_document_promise.then(function (found_document) {
if (found_document != null) {
console.log("Redundant document. Perhaps a Pair Eyewear engineer was running a test?");
res.status(200);
message = "Redundant document. Perhaps a Pair Eyewear engineer was running a test? documentType: " + documentType;
res.send(message);
} else {
new AMS_945({
shipment_header : shipment_header,
addresses : addresses,
order_header : order_header,
cartons : cartons,
unique_id : unique_id
})
.save()
.then(function () {
// console.log("saved AMS_945");
message = "saved AMS_945";
res.status(200);
res.send(message);
})
.catch(function (err) {
message = "error when saving AMS_945 to database: " + "\n\n" + err;
console.log(message);
res.status(500);
res.send(message);
});
}
})
.catch(function(err) {
message = "error when checking for a redundant AMS_945 document: " + "\n\n" + err;
console.log(message);
res.status(500);
res.send(message);
});
// down at the bottom I have some generic catch-all:
res.status(200);
res.send("Catch all response.")_;
If I don't have the catch all response at the end then the connection simply hangs until the 30 second timeout is hit, and then I get 504 Bad Gateway.
With the catch-all response at the bottom, thankfully I don't get the timeout error, but I do get an error "Sending headers after response was sent" because at some point the database code returns and tries to send its response, but this is long after the Express route function has completed and sent that generic catch-all code that I have at the bottom.
I'd be happy to get rid of the catch-all res.send() and just have the res.send() inside the database code, but that never seems to return.
So how to I get the Express route function to wait till the database code has returned?

JSON object not being sent through PUT UnityWebRequest

So, I have this code in Unity:
var www = UnityWebRequest.Put(NetworkManager.Instance.data.ConnectionURL + "/upload-schedule", contents);
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.ConnectionError)
{
Debug.LogError("There was an error uploading the schedule");
}
else {
string downloadContents = www.downloadHandler.text;
Debug.Log(downloadContents);
}
And then I have this node express application receiving this data:
app.put('/upload-schedule', (req, res) => {
var filePath = "./data/schedule.json";
var data = JSON.stringify(req.body);
// Write file
fs.writeFile(filePath, data, (err) => {
// Dip if an error is found
if (err) {
console.error(err);
return;
}
// Send found data
res.send("Successfuly uploaded file!");
console.log("Successfuly uploaded file!");
});
});
For some reason, this works fine on localhost, but, as soon as I use my web api, req.body always comes out empty. Does anyone know the reason for this and how I can fix it? Thank you

Create a middleware to verify a response object before sending the response

I'm building a small CRUD app on the Express framework. I want to have a middleware that takes all my responses and verifies them against the expected object schemas. The issue what I'm currently facing is that I don't know where to put this middleware. I've tried to put it globally after my routes and the error handler middleware, but it didn't work for some reason. When I sticked it before my defined routes this middleware worked, but didn't have the required data from a route handler. I'm pretty familiar with the middleware concept in Express, but only for requests.
If you don't have a specific answer for this issue, please feel free to share your opinion if it helps to verify all outbound response. Thanks.
Any help is appreciated.
I can give you an example usage. You can modify the response object as you desire.
// ResponseHandler.js
// Creating a response object
class ResponseHandler{
constructor(statusCode, body, success = 1){
this.statusCode = statusCode;
this.body = body;
this.body.success = success ? success : (statusCode == 200 ? 1 : 0);
}
}
module.exports = ResponseHandler;
// responseHandler.js
const ResponseHandler = require('./ResponseHandler');
const responseValidator = (err, req, res, next) => {
let res = res;
if (!(res instanceof ResponseHandler)) {
const statusCode = res.statusCode;
const body = res.body;
const success = res.body.success;
res = new ResponseHandler(statusCode, body, success);
}
next(res);
};
const responseHandler = (err, req, res, next) => {
const response = responseValidator(res);
res.status(response.statusCode).send(response.body);
};
module.exports = {
responseHandler
};
// Usage
// In index.js (After defining your routes)
app.use(responseHandler);
// In controller
let res = {
statusCode: 200,
body: {
success: 1, // Optinal
message: "This is a success message."
}
}
return next(res);

'ERR_HTTP_HEADERS_SENT' after POST request in Node.js/ Express app with request http client

The line res.send("Successfully saved the new address."); throws the
'ERR_HTTP_HEADERS_SENT' error.
I read through other posts concerning the same error and tried return res.send("Successfully saved the new address."), but that doesn't fix it. Any insights?
Note: I am new to this.
Please be kind.
Thanks.
My Code
app.post("/", function(req, res) {
const url = "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?";
const street = req.body.street;
const city = req.body.city;
const state = req.body.state;
const zip = req.body.zip;
const yourAddress = "Address=" + street.replace(" ", "+") + "&City=" + city.replace(" ", "+") + "&Zip=" + zip;
const parameters = "&category=&outFields=*&forStorage=false&f=json";
request(url + yourAddress + parameters, function(error, response, body) {
const data = JSON.parse(body);
const newAddress = data.candidates[0].address;
const longitude = data.candidates[0].location.x;
const latitude = data.candidates[0].location.y;
const address = new Address({
address: newAddress,
latitude: latitude,
longitude: longitude
});
address.save(function(err) {
if (!err) {
res.send("Successfully saved the new address.");
} else {
res.send(err);
}
});
});
res.redirect("/");
});
You are doing both res.send() and res.redirect() in the same request handler. You can't send two responses to the same request. That's what generates the warning message you see.
Pick one of the other. You either want to send an appropriate status about the .save() or you want to redirect. One or the other, not both.
In this particular code, the res.redirect() happens first so it's what the client sees. Then, after that and when the request() and the address.save() have both completed, then you try to res.send(), but that is blocked because a response has already been sent and the http connection is already done.
If you just want to redirect upon successful save, you can remove the existing res.redirect() and change to this:
address.save(function(err) {
if (!err) {
res.redirect("/");
} else {
console.log(err);
res.sendStatus(500);
}
I would Agree With #jfriend00 answer , since there can be only one response for the request .
Here's what you can do:
address.save(function(err) {
if (!err) {
res.redirect('/success')
} else {
res.send(err);
}
});
//add a new route
app.get('/success',(req,res)=>{res.send('Successfully saved the new address.')})
And then you can redirect to the home page.
This is just a workaround in this case and can differ logically in each case depending on the requirement
The Other Way is to redirect on the client side itself
eg:If you're on jquery
$.ajax({
statusCode: {
200: function() {
$(location).attr('href', 'to the homepage')
}
}
});

MongoDB query inside query

I'm new to mongoDB, Nodejs and express your helps would be more appreciated.
In below code i'm trying to find and get the remaining count from the collection model "examConfigModel" by passing the examcode, and there is check for remaining count if its greater the 0 then find another collection model "examRegisterModel" based on examcode and then there is a check to avoid duplicate entry to DB. If its unique then save the document else return error message "message:"Already Registered"". But after running the code the save is working fine but i'm getting below error and node server will stop.
Please help me how can i deal with multiple queries within a query.
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ServerResponse.setHeader (_http_outgoing.js:498:3)
at ServerResponse.header (C:\practice\angular2\student-reg-app\node_modules\express\lib\response.js:767:10)
at ServerResponse.send (C:\practice\angular2\student-reg-app\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\practice\angular2\student-reg-app\node_modules\express\lib\response.js:267:15)
at C:\practice\angular2\student-reg-app\server\routes\api.js:208:17
at C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:4495:16
at model.$__save.error (C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:396:7)
at C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:315:21
at next (C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:209:27)
at Kareem.execPost (C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:217:3)
at _cb (C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:307:15)
at $__handleSave (C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:310:5)
at C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:193:7
at result (C:\practice\angular2\student-reg-app\node_modules\mongodb\lib\utils.js:414:17)
at session.endSession (C:\practice\angular2\student-reg-app\node_modules\mongodb\lib\utils.js:401:11)
Below is the code please help me if not clear with my Question please let me know i will provide more details.
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const usersSchemaModel = require('../models/users-schema');
const statesSchemaModel = require('../models/states-schema');
const citiesSchemaModel = require('../models/cities-schema');
const examSchemaModel = require('../models/exam-schema');
const examConfigModel = require('../models/exam-config-schema');
const examRegisterModel = require('../models/regrequests-schema');
const db = require('../config/db');
const bcrypt = require('bcryptjs');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
var jwt = require('jsonwebtoken');
mongoose.Promise = global.Promise;
mongoose.connect(db.database,(err)=>{
if(err){
res.json(err);
}else{
console.log('connected');
}
});
//Register exam
router.post('/exam/register',(req, res)=>{
examConfigModel.findOne({
examcode: req.body.exam
},function(err, result) {
if (err) {
throw err;
} else {
console.log("Rem Seats: " + result.remaining);
if(result.remaining > 0){
console.log("remaining: "+result.remaining);
const examModel = new examRegisterModel();
examModel.userid = req.body.userid;
examModel.stateid = req.body.stateid;
examModel.cityid = req.body.cityid;
examModel.exam_code = req.body.exam;
examModel.father_name = req.body.father_name;
examModel.last_name = req.body.last_name;
examModel.mobileno = req.body.mobileno;
examModel.city = req.body.city;
examModel.street = req.body.street;
examModel.address = req.body.address;
examModel.zipcode = req.body.zipcode;
console.log("RequestBody: "+req.body.exam);
examRegisterModel.findOne({
exam_code: req.body.exam
},function(err, resResult) {
if (err) {
throw err;
} else {
if(resResult == null){
save(examModel,result, res);
}else{
console.log("DB: "+ resResult +" REQ: "+ req.body.exam)
if(resResult.exam_code != req.body.exam){
console.log('notEqual')
save(examModel,result, res);
}else{
console.log()
res.json({reg:'failed',message:"Already Registered",errorCode:"6001"});
}
}
}
});
}else{
res.json({reg:"failed",result:"No seat available",errorCode:7012});
}
}
});
});
function save(examModel,result,res){
examModel.save(function(err,config){
if(err){
console.log(err);
res.json(err);
}else{
console.log(result);
if(result != null){
const reduceCount = result.remaining-1;
res.json({reg:'success',rem:reduceCount,e_id:result._id,errorCode:""});
}
res.json({reg:'success',errorCode:""});
}
});
}
//Update Exam Config
router.put('/update/config/:id',(req, res)=>{
examConfigModel.findByIdAndUpdate(req.params.id,{
$set : {remaining:req.body.rem}
},
{
new : true
},
function(err,updatedExamConfig){
if(err){
console.log(err);
res.json(err);
}else{
res.json({config:'success'});
}
})
});
The reason why you are getting error Can't set headers after they are sent. is because your code has already send back response earlier and trying to send back another response. API has send back response to called, however function has not returned, so function continues till find a return statement or function meets an end that is closing braces.
Example with express.js:
router.post('/your/api', (req, res, next) => {
//Do things here
res.send('Sending response'); // response send
// Doing more things, this is all right
res.send('another response'); // Now error Can't set headers after they are sent.
next();
}, (req, res) => {
res.send('another response'); // Now error Can't set headers after they are sent.
});
res.send() send any kind of response and res.json() send only json response. Use any one again will get error Can't set headers after they are sent.
How to accidentally save from sending multiple response?
Use if-else efficiently.
Use only single res.send / res.json with dynamic statusCode res.status(statusCode).json(result).
Always use return if nothing else is needed to be done once response is send. Example:
```
router.post('/your/api', (req, res, next) => {
//Do things here
return res.send('Sending response'); // response send, and function returned
// Never came here.
// Doing more things, this is all right
return res.send('another response'); // Now error Can't set headers after they are sent.
next();
}, (req, res) => {
// never came here as function already returned.
return res.send('another response'); // Now error Can't set headers after they are sent.
});
```

Resources