The server is running and getting a lot of request while this route is not working all the other routes are working.
I am picking up error 404 with the following message.
my route works and after a while stops to work I don't know why and how this happens.
code example:
/images route
/**
* Root route, all validation will be done here.
* TODO:
*/
const { insertImgs,getExisting,getImg } = require('../core/DB.js');
const logger = require( '../logger/logger.js' ).getInstance();
class Images {
constructor(expressApp) {
if (!expressApp) throw 'no express app';
this.router = expressApp;
this.configure();
}
configure() {
this.router.get('/images',async (req, res, next) => {
try {
let images = await getImg(res.locals.config.siteConfig.ID, res.locals.config.siteConfig.ocrLicense)
/* merge results. */
return res.status(200).send( images );
} catch (err) {
/* log error */
console.log( 'alts failed', err );
logger.error({
type : 'req denied',
route : 'alts',
ip,
key : req.body.key,
data : req.body,
error : err
});
return res.status(503).send('Server Maintenance.');
}
});
return this.app;
}
}
module.exports = {
Images : Images
}
main.js
const express = require( "express" );
const cors = require( "cors" );
const http = require( 'http' );
const config = require( './config.js' );
const helmet = require("helmet");
/* routes */
const { Root } = require('./routes/root.js');
const { Alt } = require('./routes/alts.js');
const { Images } = require('./routes/images.js');
const { Health } = require('./routes/health.js');
const logger = require('./logger/logger.js').getInstance();
const app = express();
const server = http.createServer(app);
const port = config.port || 3003;
app.use( express.json() );
app.use( express.urlencoded( { extended: true } ) );
app.use( cors() );
app.use( helmet() );
/**
* init routes.
*/
[
Root,
Images,
Alt,
Health
].forEach(route => {
new route(app)
});
//404 last handler
app.use((req, res, next)=> {
res.status(404).send({error: 'Page not found'});
});
// error handler
app.use(function(err, req, res, next) {
// render the error page
res.status(err.status || 500);
res.send('error 404');
});
server.listen(port,()=>{
logger.log({ type : `server startup in process : ${ process.pid }` , port : port });
});
i would guess that it has to do with the fact that you are using the http module in conjunction with express.
i also wouldn't wrap each route in an object, express provides a Router class to do exactly that:
i rewrote some parts of your code to be a bit more concise:
main.js
const express = require("express")
const cors = require("cors")
const helmet = require("helmet")
const config = require('./config.js')
const logger = require('./logger/logger.js').getInstance()
const images_route = require('./routes/images.js')
const app = express()
const port = config.port || 3003
function page_not_found(req, res, next) {
return res.status(404).send({
error: 'Page not found'
})
}
function error_handler(err, req, res, next) {
res.status(err.status || 500)
return res.send('error 404')
}
app.use(
express.json(),
express.urlencoded({ extended: true }),
cors(),
helmet()
)
app.use('/images', image_route)
app.use(error_handler)
app.all('/', page_not_found)
app.listen(port, () => {
logger.log({
type: `server startup in process : ${ process.pid }`,
port: port
})
});
images.js
const express = require('express')
const route = express.Router()
const { insertImgs, getExisting, getImg } = require('../core/DB.js')
const logger = require('../logger/logger.js').getInstance()
route.get('/', async (req, res, next) => {
try {
let images = await getImg(
res.locals.config.siteConfig.ID,
res.locals.config.siteConfig.ocrLicense
)
return res
.status(200)
.send( images )
} catch (err) {
console.error('alts failed', err)
logger.error({
type: 'req denied',
route: 'alts',
ip,
key: req.body.key,
data: req.body,
error: err
})
return res
.status(503)
.send('Server Maintenance');
}
})
module.exports = route
it is much easier to see what routes are being used from your main.js file now, this makes it harder to have overlapping endpoints.
let me know if this helps at all.
try/catch does not work with async code. You also should not be using await inside a route handler as doing so may prevent other requests from getting processed.
Instead of this code:
this.router.get('/images',async (req, res, next) => {
try {
let images = await getImg(res.locals.config.siteConfig.ID, res.locals.config.siteConfig.ocrLicense)
/* merge results. */
return res.status(200).send( images );
} catch (err) {
/* log error */
console.log( 'alts failed', err );
logger.error({
type : 'req denied',
route : 'alts',
ip,
key : req.body.key,
data : req.body,
error : err
});
return res.status(503).send('Server Maintenance.');
}
});
Try this modified version:
this.router.get('/images', (req, res) => {
getImg(
res.locals.config.siteConfig.ID,
res.locals.config.siteConfig.ocrLicense
).then(images => {
res.status(200).send(images);
}).catch(err => {
console.log('alts failed', err);
logger.error({
type : 'req denied',
route : 'alts',
ip,
key : req.body.key,
data : req.body,
error : err
});
res.status(503).send('Server Maintenance.');
});
});
This assumes that getImg is either declared as an async function or returns a Promise.
Related
I am new to javascript and I have a a bit of a clarification question.I managed to set up a middleware function to upload image files in node.js on my App.js file. However, The route I want my images to show is the '/post' but I am stuck on how to implement my function in my Post controller 'CREATE' method as currently on my app.js file the route post is already being used in app.use("/posts", tokenChecker, postsRouter);. And I know you can't use one route in 2 separate places. Any clarification would be appreciated.
//controller file
const Post = require("../models/post");
const TokenGenerator = require("../models/token_generator");
const PostsController = {
Index: (req, res) => {
Post.find(async (err, posts) => {
if (err) {
throw err;
}
const token = await TokenGenerator.jsonwebtoken(req.user_id)
res.status(200).json({ posts: posts, token: token });
});
},
Create: (req, res) => {
const post = new Post(req.body);
post.save(async (err) => {
if (err) {
throw err;
}
const token = await TokenGenerator.jsonwebtoken(req.user_id)
res.status(201).json({ message: 'OK', token: token });
});
},
};
module.exports = PostsController;
//app.js file
const createError = require("http-errors");
const express = require("express");
const path = require("path");
const logger = require("morgan");
const JWT = require("jsonwebtoken");
const postsRouter = require("./routes/posts");
const tokensRouter = require("./routes/tokens");
const usersRouter = require("./routes/users");
const multer = require('multer');
const app = express();
// setup for receiving JSON
app.use(express.json())
app.use(logger("dev"));
app.use(express.json());
app.use(express.static(path.join(__dirname, "public")));
// middleware function to check for valid tokens
const tokenChecker = (req, res, next) => {
let token;
const authHeader = req.get("Authorization")
if(authHeader) {
token = authHeader.slice(7)
}
JWT.verify(token, process.env.JWT_SECRET, (err, payload) => {
if(err) {
console.log(err)
res.status(401).json({message: "auth error"});
} else {
req.user_id = payload.user_id;
next();
}
});
};
//middleware function for storing images
const fileStorageEngine = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '../public/images/')
},
filename:(req, file, cb) => {
}
})
const upload = multer({storage: fileStorageEngine});
app.post('/posts', upload.array('images', 3),(req,res) =>{
console.log(req.files);
res.send("multiple Files Upload success");
});
// route setup
app.use("/posts", tokenChecker, postsRouter);
app.use("/tokens", tokensRouter);
app.use("/users", usersRouter);
// catch 404 and forward to error handler
app.use((req, res, next) => {
next(createError(404));
});
// error handler
app.use((err, req, res) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// respond with details of the error
res.status(err.status || 500).json({message: 'server error'})
});
module.exports = app;
// route setup
app.use("/posts", tokenChecker, postsRouter);
app.use("/tokens", tokensRouter);
app.use("/users", usersRouter);
// catch 404 and forward to error handler
app.use((req, res, next) => {
next(createError(404));
});
// error handler
app.use((err, req, res) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// respond with details of the error
res.status(err.status || 500).json({message: 'server error'})
});
module.exports = app;
When I make a post request to the /login endpoint in postman it works fine and returns all the information. However when I try to navigate to the end point in the url the route returns unfound. In the console I get GET http://localhost:5000/login 404 (Not Found). Why is the console returning for a get request? If I try to call the post request in axios I get xhr.js:177 POST http://localhost:3000/login 404 (Not Found).
app.js
require("dotenv").config();
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const router = express.Router();
const cors = require('cors');
const app = express();
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
const mongoose = require('mongoose');
const connection = "password"
mongoose.connect(connection, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
})
const clientRoutes = require('./routes/clientRoutes');
const traderRoutes = require('./routes/traderRoutes');
const loginRoute = require('./routes/loginRoute')
app.use('/', clientRoutes, traderRoutes, loginRoute);
// setup a friendly greeting for the root route
app.get('/', (req, res) => {
res.json({
message: 'Welcome to the REST API for Pave!',
});
});
// send 404 if no other route matched
app.use((req, res) => {
res.status(404).json({
message: 'Route Not Found',
});
});
// setup a global error handler
app.use((err, req, res, next) => {
if (enableGlobalErrorLogging) {
console.error(`Global error handler: ${JSON.stringify(err.stack)}`);
}
res.status(err.status || 500).json({
message: err.message,
error: {},
});
});
app.listen(5000, () => console.log('Listening on port 5000!'))
loginRoute.js
require("dotenv").config();
const express = require("express");
const router = express.Router();
const jwt = require("jsonwebtoken");
const bcryptjs = require("bcryptjs");
const Client = require("../models/clientSchema");
const Trader = require("../models/traderSchema");
function asyncHandler(callback) {
return async (req, res, next) => {
try {
await callback(req, res, next);
} catch (error) {
next(error);
console.log(error);
}
};
}
router.post('/login', asyncHandler(async (req, res, next) => {
let user = req.body;
const trader = await Trader.findOne({ emailAddress: req.body.emailAddress })
if (user && trader) {
console.log(trader)
let traderAuthenticated = await bcryptjs.compareSync(user.password, trader.password);
console.log(traderAuthenticated)
if (traderAuthenticated) {
console.log('Trader match')
const accessToken = jwt.sign(trader.toJSON(), process.env.ACCESS_TOKEN_SECRET)
res.location('/trader');
res.json({
trader: trader,
accessToken: accessToken
}).end();
} else {
res.status(403).send({ error: 'Login failed: Please try again'}).end();
}
} else if (user && !trader) {
const client = await Client.findOne({emailAddress: req.body.emailAddress})
console.log(client)
let clientAuthenticated = await bcryptjs.compareSync(user.password, client.password);
console.log(clientAuthenticated)
if (clientAuthenticated) {
console.log('Client match')
const accessToken = jwt.sign(client.toJSON(), process.env.ACCESS_TOKEN_SECRET)
res.location('/client');
res.json({
client: client,
accessToken: accessToken
});
} else {
res.status(403).send({ error: 'Login failed: Please try again'}).end();
}
} else {
res.status(403).send({ error: 'Login failed: Please try again'}).end();
}
})
);
module.exports = router;
You set POSTMAN to make a POST request, right? When you enter a url in the browser, that causes a GET request - and you have no route to manage this that I can see, but for the default Not found.
you are calling with axios with wrong port no. it should, POST method http://localhost:5000/login as your application is running on port 5000.
but you are calling, POST http://localhost:3000/login
This below code is my first react application. After running server.js. After entering "http://localhost:8001/" I got HELLO!!. I expected after entering "http://localhost:8001/tinder/cards" url on chrome and postman too I get following error.
error message: "Cannot GET /tinder/cards".
this is my server.js file.
import mongoose from 'mongoose'
import Cors from 'cors'
import Cards from './dbCards.js'
// App Config
const app = express()
const port = process.env.PORT || 8001
const connection_url = 'mongodb+srv://admin:0tRkopC1DKm4ym4V#cluster0.iw73w.mongodb.net/tinderDB?retryWrites=true&w=majority'
// Middlewares
app.use(express.json())
app.use(Cors())
app.use('/',router);
// DB Config
mongoose.connect(connection_url, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
})
// API Endpoints
app.get("/", (req, res) => res.status(200).send("HELLO!!"))
app.get("/hello", (req, res) => res.status(200).send("Oooooooo!!"))
app.post("/tinder/cards", (req, res) => {
const dbCard = req.body
Cards.create(dbCard, (err, data) => {
if(err) {
res.status(500).send(err)
} else {
res.status(201).send(data)
}
})
})
app.get("/tinder/cards", (req, res) => {
Cards.find((err, data) => {
if(err) {
res.status(500).send(err)
} else {
res.status(200).send(data)
}
})
})
// Listener
app.listen(port, () => console.log(`listening on location: ${port}`)) ```
try this in your app.get('/tinder/cards') section:
// Doing it the Asynchronous way
app.get('/tinder/cards', async (req, res) => {
try { // Trying for getting the cards
const allCards = await Cards.find(); // Getting the cards
res.status(200).send(allCards); // Sending the cards
} catch (error) { // Catching the error
res.status(500).send(error); // Sending the error
}
});
Try to replace cards with card in the URL. Have a look at the image for the same.
how u doing?
Here is my code:
const router = Router();
router.use(
`${routePrefix}/v1/associate-auth/`,
associateAuthRoutesV1(router)
);
router.use(
`${routePrefix}/v1/associate/`,
JWTVerify,
associateRoutesV1(router)
);
app.use('/', router);
Here is an exemple of my routes content:
router.post('/', async (_req, res) => {
res.send('OK');
});
The problem is:
When I don't set the root('/') in one of routes file, Express find the next file with the same method in root ('/').
How can I configure to return 404 when there is no route specify?
use http-errors module and create 2 middlewares, the first for error handler, and the second for endpoint handler :
error handler in errorHandler.js
function checkError (err,req,res,next) => {
return res.status(err.status || 500).json({
code: err.status || 500,
status: false,
message: err.message
})
}
module.exports = checkError
endpoint handler in endpointHandler.js
// endpoint handler in endpointHandler.js
const isError = require('http-errors')
function checkRoute(req,res,next) +> {
return next(isError.NotFound('invalid endpoint')
}
module.exports = checkRoute
then in your main js :
const app = require('express')
const checkError = require('./errorHandler.js')
const checkRoute = require ('./endpointHandler.js')
const router = Router();
router.use(
`${routePrefix}/v1/associate-auth/`,
associateAuthRoutesV1(router)
);
router.use(
`${routePrefix}/v1/associate/`,
JWTVerify,
associateRoutesV1(router)
);
app.use('/', checkRoute, router);
app.use(checkError)
I am creating a sveltejs/sapper app. I am trying to post some info from the frontend to the backend express server using axios in the script tag. Although get requests from external sources are succeeding, axios is throwing a 404 error while posting to the express route. Refer these images posted below.
server.js
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
import sirv from 'sirv';
import * as sapper from '#sapper/server';
const app = express();
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
app.use(
sirv('static', {dev}),
sapper.middleware(),
bodyParser.json(),
bodyParser.urlencoded({extended:true})
);
app.post('/task', (req, res) => {
res.sendStatus(200);
console.log(req.body);
// fs.writeFile(`./downloads/${req.body.file}`, req.body.buffer, (err) => {
// if (err) throw err;
// console.log(`${res.file} downloaded to backend server`);
// });
});
app.listen(PORT, err => {
if (err) console.log('error', err);
});
frontend script
<script>
//variables
let start = false;
let url = '';
let filename = '';
let downloadProgress = 0;
let error = false;
let progressBarStyle = 'bg-success';
//automated Events
$:downloadLabel = downloadProgress.toString();
$:if(downloadLabel == '100') {
progressBarStyle = 'bg-warning';
downloadLabel = 'DOWNLOAD COMPLETE! FILE WILL BE TRANSFERED SHORTLY!';
}
//axios config
let config = {
onDownloadProgress: progressEvent => {
downloadProgress = Math.floor((progressEvent.loaded * 100) / progressEvent.total); }
}
//functions
function startDownload() {
start = true;
axios.get(url, config).then((res) => {
if(res.status == 200) {
let data = {
file: filename,
buffer: res.data
}
axios.post('/task', data).then(() => {
console.log('Data sent to server');
}).catch((err) => {
console.log(err);
});
}
else {
error = true;
}
}).catch((err) => {
error = true;
});
}
function reset() {
// start = false;
// url = '';
// filename = '';
// downloadProgress = 0;
window.location.reload();
}
</script>
browser console
network tab
You use sapper,
Try to read docs.
example:
const express = require('express');
import sirv from 'sirv';
import compression from 'compression';
import * as sapper from '#sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
const app = express();
app
/* add your handlers here */
.post('/task', (req, res, next) => {
res.sendStatus(200);
console.log(req.body);
})
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.listen(PORT, err => {
if (err) console.log('error', err);
});
I find here solution
You have to send something in the request handler:
(req, res) => {
res.sendStatus(200);
}