Error: connect ECONNREFUSED 127.0.0.1:5000 - node.js

I´ve the file cases.js to create the route I want:
const express = require("express");
const { requireSignin } = require("../controllers/auth");
const { getCases } = require("../controllers/cases");
const { scrapingData } = require("../scrapingData");
const router = express.Router();
router.get("/cases", requireSignin, scrapingData, getCases);
module.exports = router;
requireSignin from controllers/auth looks like this:
exports.requireSignin = expressJwt({
secret: process.env.JWT_SECRET,
userProperty: "auth",
});
scrapingData as middleware I have:
const updateMongoRecords = async () => {
mongoose.Promise = global.Promise;
mongoose.set("debug", true);
Case.deleteMany({}, (err, result) => {
if (err) {
console.log(err);
} else {
console.log("Successfully deleted all records");
}
});
const dataPath = Path.join(__dirname, "files", "covid-data.csv");
try {
let headers = Object.keys(Case.schema.paths).filter(
(k) => ["_id", "__v"].indexOf(k) === -1
);
await new Promise((resolve, reject) => {
let buffer = [],
counter = 0;
let stream = fs
.createReadStream(dataPath)
.pipe(csv())
.on("error", reject)
.on("data", async (doc) => {
stream.pause();
buffer.push(doc);
counter++;
// log(doc);
try {
if (counter > 10000) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
}
} catch (e) {
stream.destroy(e);
}
stream.resume();
})
.on("end", async () => {
try {
if (counter > 0) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
resolve();
}
} catch (e) {
stream.destroy(e);
}
});
});
} catch (e) {
console.error(e);
} finally {
process.exit();
}
};
exports.scrapingData = async (req, res, next) => {
const url = "https://covid.ourworldindata.org/data/owid-covid-data.csv";
const path = Path.resolve(__dirname, "files", "covid-data.csv");
const response = await Axios({
method: "GET",
url: url,
responseType: "stream",
});
response.data.pipe(fs.createWriteStream(path));
return new Promise((resolve, reject) => {
response.data.on("end", () => {
resolve(updateMongoRecords());
next();
});
response.data.on("error", (err) => {
reject(err);
});
});
};
And getCases.js inside controllers/cases I have:
const Case = require("../models/case");
exports.getCases = async (req, res) => {
const cases = await Case.find().then((cases) => res.json(cases));
};
With this code I am able to fetch in the route /cases all the cases in the client side (like postman) and it shows all of them. But the problem is that I can´t make any other requests (like signing out, which works fine if I don´t make the get request for the cases like before) afterwards because client (postman) gives the error: GET http://localhost:5000/signout
Error: connect ECONNREFUSED 127.0.0.1:5000
in case you want to see the code for signout is like this:
const express = require("express");
const { signup, signin, signout } = require("../controllers/auth");
const router = express.Router();
router.post("/signup", userSignupValidator, signup);
router.post("/signin", userSigninValidator, signin);
router.get("/signout", signout);
inside controllers/auth.js:
exports.signout = (req, res) => {
res.clearCookie("t");
return res.json({ message: "Signout successfully done" });
};
Any help on this??

Related

Azure: INFO - Waiting for response to warmup request for container ... Elapsed time = x sec

My app fails on prod and can't find a way how to fix. It works on another environments.
Some logs from the console:
2022-08-22T23:56:05.760Z INFO - Waiting for response to warmup request for container projectprod-fe_0_fd84e. Elapsed time = [225.2643051] sec
2022-08-22T23:56:35.818Z ERROR - Container projectprodfe_0_fd84e for site teamgullitpreview-fe did not start within expected time limit. Elapsed time = 255.322965 sec
It is next.js app and I create middlewares for it.
const next = require('next');
const { parse } = require('url');
nextMiddleware
async function nextMiddleware(dev = false) {
const app = next({ dev });
const handle = app.getRequestHandler();
await app.prepare();
return function nextHandler(req, res) {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
};
}
redirectMiddleware
const path = require('path');
const fs = require('fs');
const staticFiles = ['_next', '/', 'images', 'api'];
const getRedirect = async (srcPath) => {
try {
const url = `${process.env.NEXT_PUBLIC_apiUrl}/redirect?path=${srcPath}`;
const response = await fetch(url);
const json = await response.json();
return json;
} catch (e) {
throw new Error(e);
}
};
function redirecter(pathname) {
return new Promise((resolve, reject) => {
const pathParts = pathname.split('/');
if (staticFiles.indexOf(pathParts[1]) > -1) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
const possibleFile = `${path.resolve(
__dirname,
'../../public',
)}${pathname}`;
if (fs.existsSync(possibleFile)) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
getRedirect(pathname)
.then((result) => {
resolve({
shouldRedirect: true,
redirectData: result,
});
})
.catch((e) => {
reject(e);
});
}
}
});
}
async function redirectMiddleware(req, res, next) {
const parsedUrl = parse(req.url, true);
const { pathname } = parsedUrl;
try {
const { shouldRedirect, redirectData } = await redirecter(pathname);
if (shouldRedirect && redirectData.destination) {
const redirectUri = `${process.env.NEXT_PUBLIC_hostname}${
redirectData.type ? redirectData.type : ''
}${redirectData.destination}`;
res.writeHead(redirectData.statusCode[0], {
Location: redirectUri,
});
res.end();
}
} catch (e) {
next();
} finally {
next();
}
}
What I do wrong in this file or whenever?
const http = require('http');
const express = require('express');
const redirectMiddleware = require('./src/server/redirectMiddleware');
const nextMiddleware = require('./src/server/nextMiddleware');
const port = process.env.PORT || 3000;
async function bootstrap() {
const isDevelopment = process.argv.includes('--dev');
const app = express();
app.use(await redirectMiddleware);
app.use(await nextMiddleware(isDevelopment));
const server = http.createServer(app);
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
}
bootstrap().catch((err) => {
console.error('something went wrong booting up the server.');
console.error(err);
process.exit(1);
});
I have no idea what's wrong and how to debugg it. Is anyone who experienced it before?

Fastifyis not defined and fastify-postgres Fastify.pg.connect not working

I have defined my fastify like so:
const fastify = require('fastify')({logger: true})
fastify
.register(require('./setup/envs'))
.after(async (err) => {
if (err) console.log(err);
fastify.register(require('./setup/db'))
await fastify.after()
fastify.register(require('./setup/jwt'))
await fastify.after()
fastify.register(require('./setup/auth'))
await fastify.after()
// load routes
// fastify.register(require('./routes/test'))
fastify.register(require('./routes/posts/index'), { prefix: '/posts' })
})
const start = async () => {
try {
await fastify.ready()
fastify.listen(3000)
} catch (e) {
fastify.log.error(e)
process.exit(1)
}
}
start();
Now in my post routes, I have the following:
const postRoutes = require('../../controllers/posts');
async function PostRoutes(fastify, options) {
fastify.addHook('preValidation', fastify.verifyJWT)
fastify.addHook('preHandler', function (req, reply, done) {
if (req.body) {
req.log.info({ body: req.body }, 'parsed body')
}
if (req.params) {
req.log.info({ params: req.body }, 'parsed params')
}
done()
})
// get all posts
fastify.get('/:limit/:page', postRoutes.getPosts)
fastify.post('/signup', async (req, reply) => {
// some code
const token = fastify.jwt.sign({ test: 'hello' })
reply.send({ token })
})
fastify.get(
"/test-auth",
async function(request, reply) {
return { test: 'auth' }
}
)
}
module.exports = PostRoutes;
and my controller file is the following:
const fastify = require('fastify');
const getPosts = async (req, reply) => {
try {
const client = await fastify.pg.connect()
const { rows } = await client.query(
'SELECT * FROM POSTS LIMIT $1 OFFSET $2;', [req.params.limit, req.params.offset],
)
client.release()
return rows
} catch (e) {
req.log.error('Getting posts failed with params')
throw new Error(e)
}
}
module.exports = {
getPosts,
};
The const client = await fastify.pg.connect() is giving me fastify is not defined and if I require it by adding const fastify = require('fastify') at the top, I get TypeError: Cannot read properties of undefined (reading 'connect').
the following is my db.js:
const fastifyPlugin = require('fastify-plugin');
const fastifyPostgres = require('fastify-postgres');
async function dbConnector (fastify, options) {
const dbUser = encodeURIComponent(fastify.config.DATABASE_USERNAME)
const dbPassword = encodeURIComponent(fastify.config.DATABASE_PASSWORD);
const dbHost = encodeURIComponent(process.env.DATABASE_HOST);
const dbName = encodeURIComponent(fastify.config.DATABASE_NAME);
fastify.register(fastifyPostgres, {
connectionString: `postgres://${dbUser}:${dbPassword}#${dbHost}/${dbName}`
})
}
// Wrapping a plugin function with fastify-plugin exposes the decorators
// and hooks, declared inside the plugin to the parent scope.
module.exports = fastifyPlugin(dbConnector);
I had to change my route to
fastify.get('/:limit/:page', (req, reply) => postRoutes.getPosts(fastify, req, reply))
and then I was able to access the fastify object in my controller.

Using Sockets.io with React.js + Hooks; sockets.emit Not Working

I am at a complete loss as to why this is not working, I am new to using Hooks in react however want to try.
This app basically connects sockets.io to the server using sockets-auth server emits the time every 1s <- this shows me that the connection is definitely live. It then uses sockets.emit to receive an array of data, this functions. The part that doesn't is a simple button press fails to achieve anything (see both 'Save Changes' buttons at bottom of React element). No error, no response, no acknowledgment at all. I have tried it inline, in its own function. The exact same server routes are functional simultaneously running a separate app with class components.
Help would be much appreciated. Anyway here is some code..
Client-Side (React.js)
import React, { Component,useState, useEffect } from "react";
import io from "socket.io-client";
import './Secret.css'
const Secret = () => {
const [time, setTime] = useState('');
const [userlist, setUserlist] = useState([]);
const socketUrl = 'http://localhost:3001';
let socket = io(socketUrl, {
autoConnect: false,
});
useEffect(() => {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'React POST Request Example' })
};
fetch('/api/connectsocket', requestOptions)
.then(async response => {
const data = await response.json();
if (!response.ok) {
const error = (data && data.message) || response.status;
return Promise.reject(error);
}
console.log(data)
connectSocket(data)
})
.catch(error => {
console.error('There was an error!', error);
});
}, [socketUrl]);
const connectSocket= (data)=>{
let dataUser = data
console.log(dataUser.email)
let error = null;
socket.on('connect', () => {
console.log('Connected');
socket.emit('authentication', {
token: dataUser.email,
i: dataUser.i
});
});
socket.on('unauthorized', (reason) => {
console.log('Unauthorized:', reason);
error = reason.message;
socket.disconnect();
});
socket.on('disconnect', (reason) => {
console.log(`Disconnected: ${error || reason}`);
error = null;
});
socket.on("admin connected", data => {
socket.emit('admin userlist', { get:'x',for:'who' }, (error) => {
if(error) {
alert(error);
}
});
console.log(data)
});
socket.on("admin user list", data => {
setUserlist(data)
console.log(data)
});
socket.on("FromAPI", data => {
setTime(data)
console.log(data)
});
socket.open();
}
const sendMessage = (x)=>{
console.log(x)
socket.emit('hello', 'JSON.stringify(x)');
}
const doSomething = ()=>{
socket.emit('chatmessage', {msg:"Hello"});
}
return (
<div>
<div className="outerContainer">
<div className="container">
{time}
<button onClick={sendMessage}>Save Changes</button>
<button onClick={doSomething}>Save Changes</button>
{userlist.map(user => (
<tr key={user.id} value={user.id}>
<td>{user.email}</td>
<td>{user.email}</td>
<td>{user.email}</td>
</tr>
))}
</div>
</div>
</div>
);
}
export default Secret
Server-side (Node.js)
const http = require('http');
const cors = require('cors');
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const io = require('socket.io')();
const socketAuth = require('socketio-auth');
//custom modules
const router = require('./modules/router');
const db = require('./modules/db.js');
const prettyDate = require('./modules/prettyDate.js');
const sortArray = require('./modules/sortArray.js');
const app = express();
const server = http.createServer(app);
io.attach(server);
app.use(cors()); ///delete for production
app.use(bodyParser.urlencoded({ extended: true }));
app.use(fileUpload({
createParentPath: true
}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(router);
app.use(express.static('public'))
db.i12345.sessions.persistence.setAutocompactionInterval(400)
////Sessions Store; not important if you want to run the code without
function setUser(id,user,i){
console.log('setuser')
let institution = i
db[institution].sessions.find({ user:user }, function (err, docs) {
if(docs.length){
db[institution].sessions.update({user:user }, { $set: { id: id } }, { multi: true }, function (err, numReplaced) {
});
} else {
var d = new Date();
var n = d.getTime();
var doc = { user: user
, id: id
, t:n
};
db[institution].sessions.insert(doc, function (err, newDoc) {
});
}
});
}
///user verification; could easily mock; if wanting to actually run code
async function verifyUser (token,i) {
var institution =i
return new Promise((resolve, reject) => {
// setTimeout to mock a cache or database call
setTimeout(() => {
var user = new Promise((resolve,reject) =>{
db[institution].users.find({email:token}, function (err, docs) {
if(docs.length){
resolve(docs);
} else {
reject(false)
}
});
});
if (!user) {
return reject('USER_NOT_FOUND');
}
return resolve(user);
}, 200);
});
}
//// Sockets auth implementation
socketAuth(io, {
authenticate: async (socket, data, callback) => {
const { token, i } = data;
console.log(data)
try {
const user = await verifyUser(token, i);
socket.user = user;
socket.i = i
console.log(i)
return callback(null, true);
} catch (e) {
console.log(`Socket ${socket.id} unauthorized.`);
return callback({ message: 'UNAUTHORIZED' });
}
},
postAuthenticate: async (socket) => {
console.log(`Socket ${socket.id} authenticated.`);
console.log(socket.user)
setUser(socket.id,socket.user, socket.i)
socket.emit('empty list', {queryList:true});
io.emit('admin connected', {admin:true});
socket.conn.on('packet', async (packet) => {
if (socket.auth && packet.type === 'ping') {
}
});
socket.on('chatmessage', (msg) => {
io.emit('chatmessage', msg);
console.log(msg);
});
socket.on('hello', (msg) => {
io.emit('chatmessage', msg);
console.log(msg);
});
socket.on('get tasks', (get) => {
let i = socket.i
let user = socket.user
getTasksChunk(get,i,user)
});
socket.on('admin userlist', (get) => {
let i = socket.i
let user = socket.user
adminGetUserList(get,i,user)
});
socket.on('admin roles', (data) => {
let i = socket.i
let user = socket.user
console.log(data)
console.log('reaced')
});
interval = setInterval(() => getApiAndEmit(socket), 1000);
},
disconnect: async (socket) => {
console.log(`Socket ${socket.id} disconnected.`);
if (socket.user) {
}
},
})
function getTasksChunk(get,i, user){
console.log(get,i,user);
let institution = i
db[institution].tasks24.find({}, async function (err, docs) {
if(docs.length){
for(i=0;i<docs.length;i++){
docs[i].location = `Ward: ${docs[i].location.Ward} Bed: ${docs[i].location.Bed}`
docs[i].patient = docs[i].patient.join(' | ')
docs[i].timestamp = prettyDate(new Date(+docs[i].timestamp))
}
console.log(docs)
let sorted = await sortArray(docs,'timestamp')
let chunk = sorted.slice(0,10)
io.emit('tasks in', chunk);
} else {
}
});
}
const getApiAndEmit = socket => {
const response = new Date();
// Emitting a new message. Will be consumed by the client
socket.emit("FromAPI", response);
};
///////ADMIN????????
function adminGetUserList(get,i,user){
var institution = i
console.log('hello')
db[institution].users.find({}, async function (err, docs) {
if(docs.length){
console.log(docs)
let sorted = await sortArray(docs,'timestamp')
io.emit('admin user list', sorted);
} else {
}
});
}
server.listen(process.env.PORT || 3001, () => console.log(`Server has started.`));
You must store your socket instance in a ref otherwise you would loose the connected socket instance when your component re-renders.
In short you need the socket reference to be the same across renders
const socketUrl = 'http://localhost:3001';
let socket = useRef(null);
useEffect(() => {
socket.current = io(socketUrl, {
autoConnect: false,
});
...
}, [socketUrl]);
Now note that whereever you are using socket you would use socket.current.
Ex:
socket,.current.on('hello', (msg) => {
io.emit('chatmessage', msg);
console.log(msg);
});

Error: Connection lost: The server closed the connection

I have just put my node.js app in a local server in order to host it, so some users will be able to use it and I am having the following issue:
Everything works fine when I run the app, even after some minutes it keeps working well. However, if I leave it running for some some days, it stops working and I get this error. For instance, I ran it the last friday and today (Monday) I have seen this error when I connected remotelly to the server.
This is my server file:
const express = require('express');
const bodyParser = require("body-parser");
const crypto = require('crypto');
var session = require('express-session');
const internalIp = require('internal-ip');
const getPrices = require('./scrapers/getPrices.js');
const dbConnection = require('./dbConnection.js');
const app = express();
app.use('/assets', express.static('./assets/'));
const localIP = internalIp.v4.sync();
var hotelNames = [];
var urlsHotels = [];
var usersList = [];
var userInfo = new Object();
userInfo.id = undefined;
userInfo.role = 0;
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true
}));
app.get('/', function (req, res) {
if (req.session.loggedin && userInfo.role == 0) {
getHotelsdata(res);
} else if (req.session.loggedin && userInfo.role == 1) {
loadAdminPage(res);
} else {
res.redirect('/login');
}
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/login',function(req,res){
globalRes = res
//res.sendFile(__dirname + "/views/login.html");
res.render('./login.ejs', {
'localIP':localIP,
});
});
app.post('/submitlogin',function(req,res){
const password = crypto.createHash('sha256').update(req.body.password).digest('hex');
const users = new Promise((resolve, reject) => {
dbConnection
.getUsers()
.then(data => {
resolve(data)
})
});
Promise.all([users])
.then(data => {
usersList = data[0];
var loginSuccess = "0";
for(var i = 0; i < data[0].length; i++) {
if(data[0][i][1] == req.body.user && data[0][i][2] == password) {
req.session.loggedin = true;
req.session.username = req.body.user;
loginSuccess = "1";
userInfo.id = data[0][i][0];
userInfo.role = data[0][i][3];
}
}
res.end(loginSuccess);
});
});
app.post('/deleteUser', function(req, res) {
const deleteUser = new Promise((resolve, reject) => {
dbConnection
.deleteUser(req.body.user)
.then(data => {
resolve(data)
response = data[0];
})
});
Promise.all([deleteUser])
.then(data=> {
getUsersData(res, response);
});
})
app.post('/changePwd', function(req, res) {
const currentPassword = crypto.createHash('sha256').update(req.body.currentPassword).digest('hex');
const newPassword = crypto.createHash('sha256').update(req.body.newPassword).digest('hex');
const changePwd = new Promise((resolve, reject) => {
dbConnection
.changePwd(currentPassword, newPassword)
.then(data => {
resolve(data)
response = data[0];
})
});
Promise.all([changePwd])
.then(data=> {
res.end(data[0]);
});
})
app.post('/addUser', function(req, res) {
const password = crypto.createHash('sha256').update(req.body.password).digest('hex');
var response;
const insertUser = new Promise((resolve, reject) => {
dbConnection
.registerUser(req.body.user, password)
.then(data => {
resolve(data)
response = data;
})
});
Promise.all([insertUser])
.then(data => {
getUsersData(res, response);
});
});
app.get('/compare/:visitDay&:visitMonth&:visitYear&:leavingDay&:leavingMonth&:leavingYear', async function(req, res, next) {
if (req.session.loggedin) {
var results = new Array();
const date1 = new Date(req.params.visitMonth + '-' + req.params.visitDay + '-' + req.params.visitYear);
const date2 = new Date(req.params.leavingMonth + '-' + req.params.leavingDay + '-' + req.params.leavingYear);
const timeDiff = Math.abs(date2.getTime() - date1.getTime());
const nights = Math.ceil(timeDiff / (1000 * 3600 * 24));
assignurls(req.params.visitYear, req.params.visitMonth, req.params.visitDay, req.params.leavingYear, req.params.leavingMonth, req.params.leavingDay);
const getPrices = new Promise((resolve, reject) => {
getPrices
.getPrices(results, nights, urlsHotels)
.then(data => {
resolve(data)
})
});
Promise.all([getPrices])
.then(data => {
loadPage(res, JSON.stringify(hotelNames), JSON.stringify(results), req.params.visitDay + "/" + req.params.visitMonth + "/" + req.params.visitYear, req.params.leavingDay + "/" + req.params.leavingMonth + "/" + req.params.leavingYear);
});
} else {
res.redirect('/login');
}
});
app.get('/addHotel&:url&:name', function(req, res, next) {
if (req.session.loggedin) {
let url = req.params.url.split('');
url.splice(44, 3);
url[44] = 'visitYear';
url.splice(46, 1);
url[46] = 'visitMonth';
url.splice(48, 1);
url[48] = 'visitDay';
url.splice(70, 3);
url[70] = 'leavingYear';
url.splice(72, 1);
url[72] = 'leavingMonth';
url.splice(74, 1);
url[74] = 'leavingDay';
url = url.join('');
const insertHotel = new Promise((resolve, reject) => {
dbConnection
.insertValues(hotelNames, url, req.params.name, userInfo.id)
.then(data => {
resolve(data)
})
});
Promise.all([insertHotel])
.then(data => {
getHotelsdata(res, data);
});
} else {
res.redirect('/login');
}
});
app.get('/deleteHotel&:name', function(req, res, next) {
if (req.session.loggedin) {
const deleteHotel = new Promise((resolve, reject) => {
dbConnection
.deleteValues(req.params.name)
.then(data => {
resolve(data)
})
});
Promise.all([deleteHotel])
.then(data => {
getHotelsdata(res, data);
});
} else {
res.redirect('/login');
}
});
app.get('/logout', function(req, res, next) {
req.session.loggedin = false;
res.redirect('/');
});
function assignurls(visitYear, visitMonth, visitDay, leavingYear, leavingMonth, leavingDay) {
for(var i = 0; i<urlsHotels.length; i++) {
var finalurl = urlsHotels[i].replace('visitYear', visitYear);
finalurl = finalurl.replace('visitMonth', visitMonth);
finalurl = finalurl.replace('visitDay', visitDay);
finalurl = finalurl.replace('leavingYear', leavingYear);
finalurl = finalurl.replace('leavingMonth', leavingMonth);
finalurl = finalurl.replace('leavingDay', leavingDay);
urlsHotels[i] = finalurl;
}
}
function getUsersData(res, response) {
const users = new Promise((resolve, reject) => {
dbConnection
.getUsers()
.then(data => {
resolve(data);
})
});
Promise.all([users])
.then(data => {
usersList = data[0];
res.end(response);
});
}
function getHotelsdata(res, results) {
const getNotelNames = new Promise((resolve, reject) => {
dbConnection
.getHotelNames(userInfo.id)
.then(data => {
resolve(data)
})
});
const getURLs = new Promise((resolve, reject) => {
dbConnection
.getURLs(userInfo.id)
.then(data => {
resolve(data)
})
});
Promise.all([getNotelNames, getURLs])
.then(data => {
hotelNames = data[0];
urlsHotels = data[1];
loadPage(res, JSON.stringify(hotelNames), JSON.stringify([results]));
});
}
function loadPage(res, param1, param2, param3, param4) {
res.render('./comparatorPage.ejs', {
'hotelNames':param1,
'results': param2,
'checkInDate': param3,
'checkOutDate': param4,
'localIP': localIP,
});
}
function loadAdminPage(res) {
res.render('./adminPage.ejs', {
'usersList': JSON.stringify(usersList),
'localIP': localIP
});
}
app.listen(process.env.PORT || 3000);
That is the error I get:
As I said, everything works fine until it is running during some days.
How can I solve this? Node.js is a sever-side language, so this should not be happening.
Thank you in advance.
Additional info: I use Windows Server 2008 R2 Standard.

koa2+koa-router+mysql keep returning 'Not Found'

Background
I am using koa2 with some middlewares to build a basic api framework. But when I use "ctx.body" to send response in my router, the client side always receive "Not Found"
My code
./app.js
const Koa = require('koa');
const app = new Koa();
const config = require('./config');
//Middlewares
const loggerAsync = require('./middleware/logger-async')
const bodyParser = require('koa-bodyparser')
const jsonp = require('koa-jsonp')
app.use(loggerAsync())
app.use(bodyParser())
app.use(jsonp());
//Router
const gateway = require('./router/gateway')
app.use(gateway.routes(), gateway.allowedMethods());
app.use(async(ctx, next) => {
await next();
ctx.response.body = {
success: false,
code: config.code_system,
message: 'wrong path'
}
});
app.listen(3000);
./router/gateway.js
/**
* Created by Administrator on 2017/4/11.
*/
const Router = require('koa-router');
const gateway = new Router();
const df = require('../db/data-fetcher');
const config = require('../config');
const moment = require('moment');
const log4js = require('log4js');
// log4js.configure({
// appenders: { cheese: { type: 'file', filename: 'cheese.log' } },
// categories: { default: { appenders: ['cheese'], level: 'error' } }
// });
const logger = log4js.getLogger('cheese');
logger.setLevel('ERROR');
gateway.get('/gateway', async(ctx, next) => {
let time = ctx.query.time;
if (!time) {
ctx.body = {
success: false,
code: config.code_system,
message: 'Please input running times'
}
} else {
try {
let r = await df(`insert into gateway (g_time, g_result, g_date) values (${time}, '',now())`);
return ctx.body = {
success: true,
code: config.code_success
}
} catch (error) {
logger.error(error.message);
}
}
});
module.exports = gateway;
Then a db wrapper(mysql)
./db/async-db.js
const mysql = require('mysql');
const config = require('../config');
const pool = mysql.createPool({
host: config.database.HOST,
user: config.database.USERNAME,
password: config.database.PASSWORD,
database: config.database.DATABASE
})
let query = (sql, values) => {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) {
reject(err)
} else {
connection.query(sql, values, (err, rows) => {
if (err) {
reject(err)
} else {
resolve(rows)
}
connection.release()
})
}
})
})
}
module.exports = query
./db/data-fetcher.js
const query = require('./async-db')
async function performQuery(sql) {
let dataList = await query(sql)
return dataList
}
module.exports = performQuery;
My running result
When I launch server on port 3000 then accesss via http://localhost:3000/gateway?time=5, it always returns "Not found". But as I can see I have already used
return ctx.body = {
success: true,
code: config.code_success
}
to send response. I debugged and found that the database processing was done well, the new data was inserted well.
when I remove that db inserting line, it works well and returns success info.
let r = await df(`insert into gateway (g_time, g_result, g_date) values (${time}, '',now())`);
Is there anything wrong?
Thanks a lot!
Update 2017/04/27
Now I have found the problem. It's due to my custom middleware
const loggerAsync = require('./middleware/logger-async')
Code are like following -
function log( ctx ) {
console.log( ctx.method, ctx.header.host + ctx.url )
}
module.exports = function () {
return function ( ctx, next ) {
return new Promise( ( resolve, reject ) => {
// 执行中间件的操作
log( ctx )
resolve()
return next()
}).catch(( err ) => {
return next()
})
}
}
I changed it to async/await way then everything is working well.
Could anyone please tell me what's wrong with this middleware?
I guess, your problem is the ./db/data-fetcher.js function. When you are calling
let r = await df(`insert ....`)
your df - function should return a promise.
So try to rewrite your ./db/data-fetcher.js like this (not tested):
const query = require('./async-db')
function performQuery(sql) {
return new Promise((resolve, reject) => {
query(sql).then(
result => {
resolve(result)
}
)
}
}
module.exports = performQuery;
Hope that helps.
correct middleware:
function log( ctx ) {
console.log( ctx.method, ctx.header.host + ctx.url )
}
module.exports = function () {
return function ( ctx, next ) {
log( ctx );
return next()
}
}
reason: when resolve involved; promise chain was completed; response has been sent to client. although middleware remained will involved, but response has gone!
try to understand It seems that if you want to use a common function as middleware, you have to return the next function
nodejs(koa):Can't set headers after they are sent

Resources