My backend in ExpressJS and NodeJS used to work well. I just realized that logs exploded the disk (the backend is still functional), because when the backend is on, it keeps trying:
kpi.js GET /socket.io/?EIO=3&transport=polling&t=NBiaEK6
index.js GET /socket.io/?EIO=3&transport=polling&t=NBiaEK6
index.js router.get *
kpi.js POST /socket.io/?EIO=3&transport=polling&t=NBiaER6
index.js POST /socket.io/?EIO=3&transport=polling&t=NBiaER6
Error: Not Found
at /opt/funfun/app.js:99:13
at Layer.handle [as handle_request] (/opt/funfun/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/funfun/node_modules/express/lib/router/index.js:317:13)
at /opt/funfun/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/opt/funfun/node_modules/express/lib/router/index.js:335:12)
at next (/opt/funfun/node_modules/express/lib/router/index.js:275:10)
at /opt/funfun/node_modules/express/lib/router/index.js:635:15
at next (/opt/funfun/node_modules/express/lib/router/index.js:260:14)
at /opt/funfun/routes/index.js:18:2
at Layer.handle [as handle_request] (/opt/funfun/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/funfun/node_modules/express/lib/router/index.js:317:13)
at /opt/funfun/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/opt/funfun/node_modules/express/lib/router/index.js:335:12)
at next (/opt/funfun/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/opt/funfun/node_modules/express/lib/router/index.js:174:3)
at router (/opt/funfun/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/opt/funfun/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/funfun/node_modules/express/lib/router/index.js:317:13)
at /opt/funfun/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/opt/funfun/node_modules/express/lib/router/index.js:335:12)
at next (/opt/funfun/node_modules/express/lib/router/index.js:275:10)
at /opt/funfun/node_modules/express/lib/router/index.js:635:15
kpi.js GET /socket.io/?EIO=3&transport=polling&t=NBiaF8A
index.js GET /socket.io/?EIO=3&transport=polling&t=NBiaF8A
index.js router.get *
kpi.js POST /socket.io/?EIO=3&transport=polling&t=NBiaFFz
index.js POST /socket.io/?EIO=3&transport=polling&t=NBiaFFz
Error: Not Found
at /opt/funfun/app.js:99:13
at Layer.handle [as handle_request] (/opt/funfun/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/funfun/node_modules/express/lib/router/index.js:317:13)
at /opt/funfun/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/opt/funfun/node_modules/express/lib/router/index.js:335:12)
at next (/opt/funfun/node_modules/express/lib/router/index.js:275:10)
at /opt/funfun/node_modules/express/lib/router/index.js:635:15
at next (/opt/funfun/node_modules/express/lib/router/index.js:260:14)
at /opt/funfun/routes/index.js:18:2
at Layer.handle [as handle_request] (/opt/funfun/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/funfun/node_modules/express/lib/router/index.js:317:13)
at /opt/funfun/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/opt/funfun/node_modules/express/lib/router/index.js:335:12)
at next (/opt/funfun/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/opt/funfun/node_modules/express/lib/router/index.js:174:3)
at router (/opt/funfun/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/opt/funfun/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/funfun/node_modules/express/lib/router/index.js:317:13)
at /opt/funfun/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/opt/funfun/node_modules/express/lib/router/index.js:335:12)
at next (/opt/funfun/node_modules/express/lib/router/index.js:275:10)
at /opt/funfun/node_modules/express/lib/router/index.js:635:15
kpi.js GET ... and index.js GET ... are what I print. Here is the code of opt/funfun/app.js:
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found'); // line 99
err.status = 404;
next(err);
});
Does anyone know what may be the reason?
This may happen if you have a socket.io client trying to connect to
your backend, but your backend does not have a socket.io server configured or
is not properly configured to accept connection and you are logging any errors in
the error handler.
Make sure the socket.io client and server are properly configured.
Please see the socket.io docs on how to setup the client and the server.
By default the client keeps trying to reconnect infinitely when the connection fails,
you can prevent it from polling the server infinitely by setting the
reconnectionAttempts options.
For example, this will prevent the client from polling the server after 10 failed attempts
const socket = io(serverURL, { reconnectionAttempts: 10 });
Also to minimize the size of your logs, don't log the entire error object when you are in production,
you could update the error handler to log only relevant details
// catch errors and forward to error handler
app.use(function (req, res, next) {
...
next(err);
});
//In the error handler
app.use(function (err, req, res, next) {
//log only relevant details
logger.info(err.message)
})
Since you are passing an Error to the next parameter, it will detects as an error and Express will use its default handler if you don't have any Error handler.
If you pass anything to the next() function (except the string 'route'), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
If you pass an error to next() and you do not handle it in a custom error handler, it will be handled by the built-in error handler; the error will be written to the client with the stack trace. The stack trace is not included in the production environment.
From: https://expressjs.com/en/guide/error-handling.html
So it might be because:
You don't have error handler middleware, and Express default error handler is logging all of the error stack traces
You have error handler, but it's logging all the error stack trace.
First, make sure you are running in production environment so the error stack trace doesn't get sent to the client
Set the environment variable NODE_ENV to production, to run the app in production mode.
If you want to pass data (error) to next middleware without it getting detected as an error, store it in res.locals instead, read more here.
app.use(function (req, res, next) {
const err = new Error("Not Found");
err.status = 404;
res.locals.exception = err;
next();
});
// Custom Error handler
app.use(function (req, res) {
let err = res.locals.exception;
// Add Minimum logging here if you want
if(err.message === "Not Found") {
return res.status(404).send();
} else {
return res.status(500).send();
}
// or
return res.status(err.status).send(err.message);
});
or write your own actual custom error handler middleware (make sure to put it after the 404 error handler)
app.use(function (req, res, next) {
const err = new Error("Not Found");
err.status = 404;
next(err);
});
// Actual Error handler Middleware, notice the first parameter is the error
app.use(function (err, req, res) {
// Add Minimum logging here if you want
if(err.message === "Not Found") {
return res.status(404).send();
} else {
return res.status(500).send();
}
// or
return res.status(err.status).send(err.message);
});
// -- or if you are using typescript --
// declare the error handler first
const errorHandler: ErrorRequestHandler = (err, req, res, next) => {
// Add Minimum logging here if you want
if(err.message === "Not Found") {
return res.status(404).send();
} else {
return res.status(500).send();
}
// or
return res.status(err.status).send(err.message);
};
// then use it
app.use(errorHandler);
I've been using the first option (res.locals) because on Typescript it doesn't support error handler middleware somehow. I just figured it out, adding it to example, found the solution from this github issue
Related
I have a Vue project and all of my routes are structured the same, however, one of them always gives me an unauthorized error.
Here are the routes:
router.get('/:userId/reviews', checkJwt, verifyUser, controller.getReviewsByUserId)
router.put('/:userId/review', checkJwt, verifyUser, controller.updateReview)
router.delete('/:userId/review', checkJwt, verifyUser, controller.removeReviewFromUser) // this is the broken route
If I were to change the broken route to:
router.put('/:userId/delete/review', checkJwt, verifyUser, controller.removeReviewFromUser)
Then it works just fine. The checkJwt middleware is where the issue is coming from. But I have 10 other routes that are structured IDENTICALLY to the delete route that is failing. Why?
Here is the checkJwt code even though this should not be where the issue is since it DOES work for all of my other 15 routes as long as the http verb is put, post, or 'get:
const { auth } = require('express-oauth2-jwt-bearer')
// Setup auth
const checkJwt = auth({
audience: 'MY-AUDIENCE',
issuerBaseURL: 'https://simplyadvanced.auth0.com/'
})
module.exports = {
checkJwt
}
And here is the full error message:
UnauthorizedError: Unauthorized
at getToken (C:\Users\cody\App\app-core\api\node_modules\express-oauth2-jwt-bearer\dist\index.js:83:15)
at C:\Users\cody\App\app-core\api\node_modules\express-oauth2-jwt-bearer\dist\index.js:353:25
at Layer.handle [as handle_request] (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\cody\App\app-core\api\node_modules\express\lib\router\index.js:281:22
at param (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\index.js:360:14)
at param (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\index.js:371:14)
at Function.process_params (C:\Users\cody\App\app-core\api\node_modules\express\lib\router\index.js:416:3)
Figured it out. DELETE requests should not have a request body so by removing the body and adding the ID to the URL request parameter, it worked.
I'm trying to use my "window" variable in express but i cant. Can anyone help
const { app, BrowserWindow } = require("electron")
const expapp = require("express")()
this.window
app.on("ready", () => {
this.window = new BrowserWindow({webPreferences:{ nodeIntegration: true }})
this.window.loadURL("https://www.google.com.tr")
expapp.get("/", (req,res) => {
res.render("index.ejs")
})
/* Sayfayı geri al */
expapp.get("/back", (req,res) => {
this.window.selectPreviousTab()
res.send("ok")
})
})
expapp.listen(1661, () => { console.log("1661 portu üzerinden dinleniyor") })
when i go to this route in express "/back" i get this error
TypeError: this.window.selectPreviousTab is not a function
at C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\app.js:15:21
at Layer.handle [as handle_request] (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\index.js:275:10)
at expressInit (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\middleware\init.js:40:5)
at Layer.handle [as handle_request] (C:\Users\GreXLin85\Desktop\Projelerim\PC\xx\node_modules\express\lib\router\layer.js:95:5)
You should read about main and renderer processes in electron:
https://www.electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
In main process you don't have global window variable: main process is node process, not a browser one.
And BrowserWindow class has no .selectPreviousTab() method - it's not an NSWindow and you are not writing native code in Swift. You should use electron/js documentation not native/Swift documentation ofr developing electron apps.
electron is a framework/platform for writing desktop applications in JS using node and chromium, it is not a native framework.
I'm trying to validate a PATCH request payload for a Todo App that should have at least a text or a value property. I'm doing so in updateTodoValidators. Both properties are optional but at least one must exist (hence the oneOf) and if any exists it must be valid as the validators outside the oneOf indicate.
const validate = (validations) => {
return async (req, res, next) => {
await Promise.all(validations.map(validation => validation.run(req)));
const errors = validationResult(req)
if (errors.isEmpty()) {
return next();
}
res
.status(422)
.json({
payload: {
errors: errors.array()
},
message: "Validation error/s",
error: true
})
}
}
const updateTodoValidators = [
oneOf([
body('text').exists().withMessage('not specified'),
body('value').exists().withMessage('not specified')
]),
body('text').optional().trim().notEmpty().withMessage('cannot be empty'),
body('value').optional().isInt({ min: 1 }).withMessage('must be a valid positive number')
]
app.patch('/todos/:id', validate(updateTodoValidators), async (req, res, next) => { /* Route handler implementation */ })
I was looking into running the validations imperatively as indicated in Running validations imperatively [docs] for code readability purposes. And I discovered that if I have some validations that involve a oneOf my validate() throws with a TypeError saying validation.run is not a function. Bellow is a stack trace detailing the error:
(node:88997) UnhandledPromiseRejectionWarning: TypeError: validation.run is not a function
at Promise.all.validations.map.validation (/Users/alejandro/code/Production/server/validators/validate.js:6:64)
at Array.map (<anonymous>)
at /Users/alejandro/code/Production/server/validators/validate.js:6:35
at Layer.handle [as handle_request] (/Users/alejandro/code/Production/server/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/alejandro/code/Production/server/node_modules/express/lib/router/route.js:137:13)
at loginRequired (/Users/alejandro/code/Production/server/auth/helpers.js:18:24)
at Layer.handle [as handle_request] (/Users/alejandro/code/Production/server/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/alejandro/code/Production/server/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/alejandro/code/Production/server/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/alejandro/code/Production/server/node_modules/express/lib/router/layer.js:95:5)
(node:88997) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:88997) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
So, my question is: Is there any way to run validations imperatively when validations might involve one or more oneOfs?
I ended up doing it manually.
Do a .run() on both param checks. Then validate the _errors property is empty on both.
export const validateTokens = async (req, res, next) => {
// Check to make sure one of the header tokens is set and a UUID
const token1 = await header('token1')
.isUUID()
.run(req);
const token2 = await header('token2')
.isUUID()
.run(req);
// Manual oneOf
if (isEmpty(token1._errors) || isEmpty(token2._errors)) {
return next();
}
// Return error results
res.status(400).send('Must include either token1 or token2');
};
oneOf returns a middleware instance, not a validation chain. It doesn't have a .run() function which your customer middleware validator uses to validate hence it is erroring out.
There is an open issue for this here
For the moment I think you would need to implement you own custom function to validate these conditional parameters.
I am trying to connect to MongoDB atlas using mongoose but always get an error,
I have tried to change my ip address and also try to change the link
also change all the settings in mongoDB altas but always get the same error
const express = require('express')
const graphqlHTTP = require('express-graphql')
const app = express()
const catSchema = require('./Schema/categorySchema')
const mongoose = require('mongoose')
// SetUp MongoDB
mongoose.connect('mongodb+srv://khawar111:khawar111#e-selling-bh1wv.mongodb.net/test?retryWrites=true&w=majority', { useNewUrlParser: true })
mongoose.connection.once('open', () => {
console.log('Database Connected')
})
mongoose.connection.on('error', (e) => {
console.log(e)
})
// Set Route for GraphQL
app.use('/graphQL', graphqlHTTP({
schema: catSchema,
graphiql: true
})
)
app.listen(3000, () => {
console.log('Server Started')
})
Error:
Error: queryTxt ETIMEOUT e-selling-bh1wv.mongodb.net
at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) {
errno: 'ETIMEOUT',
code: 'ETIMEOUT',
syscall: 'queryTxt',
hostname: 'e-selling-bh1wv.mongodb.net'
}
(node:25313) UnhandledPromiseRejectionWarning: Error: queryTxt ETIMEOUT e-selling-bh1wv.mongodb.net
at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19)
(node:25313) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:25313) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Actually,you need to remove " test?retryWrites=true&w=majority " from your connection string and replace it with the name of your database.Like this
mongoose.connect('mongodb+srv://khawar111:khawar111#e-selling-bh1wv.mongodb.net/DatabaseName', { useNewUrlParser: true })
this is because "test?retryWrites=true&w=majority" is used for testing purposes
Make sure to change the node version to 2.2.12
And add IP address like below:
I faced the issue and I try to find the answer but nothing works then after some time it works normally again . I think it is just a connection limit issue.
Error is:
event.js line number 160
Unhandled exception.
This error occured after an error was unhandled by utils.js
Due to Error: write EPROTO 139889615579008:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:../deps/openssl/openssl/ssl/s23_clnt.c:794:
App crashes immediately.
function: (req, res, next) {
var domain = require('domain');
var d = domain.create();
d.on('error', function(er) {});
d.add(req);
d.add(res);
d.run(function() {
next();
});
}
Adding this to a common function used in config/http.js worked.