I need make a conversion of a Multer Midware function('upload') using callback to works in async mode using promises.
I tried to transform the upload function in a promise.
The image sent to server continues being saved as before, but my code throw an error as:
(node:3568) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): undefined
(node:3568) [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.
when I execute the function
var resp=await uploadAsync(req, res);
What am I doing wrong?
//server code
'use strict';
const express = require('express');
const router = express.Router();
const pool = require('./pool'); // my database pool module, using promise-mysql
const Errors = require('./mysql_errors'); // my collection of custom exceptions
const HttpStatus = require('http-status-codes');
var path = require('path')
var fs = require('fs')
const fileDir='./public/images/uploads'
//imagens
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, fileDir)
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname);
}
})
const upload = multer({ storage: storage}).single('foto');
function uploadAsync(req,res){
return new Promise(function(resolve,reject){
upload(req,res,function(err){
if(err !== null) return reject(err);
resolve();
});
});
}
router.post('/foto/:id',uploadAsync, async function(req,res,next){
try{
var resp=await uploadAsync(req, res);
}catch(err) {
return res.status(500).send({ success:false, message: 'Erro', results:{} }); // 404
}
});
module.exports=router;
if(err !== null) return reject(err);
resolve();
in those conditions, you have to keep like
if(err !== undefined) return reject(err);
resolve();
as the error will be undefined is the call back returns true.
Related
I am facing an error with node/express. I am assuming the issue is with my asynchronous code design.
Output:
Success in container
Expected Output:
Success in container..
Success in Uploading...
Error: (node:18364) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
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()
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.
Code:
const express = require("express");
const multer = require("multer");
const AuthReq = require("../middleWare/AuthReq");
require("dotenv").config();
const Azure_Storage_Connection_String = process.env.Azure_Connection_String;
const { BlobServiceClient } = require("#azure/storage-blob");
const Router = express.Router();
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
},
});
const upload = multer({ storage: storage });
Router.post("/profile", AuthReq, upload.single("profile"), async (req, res) => {
const file = req.file;
const blobServiceClient = BlobServiceClient.fromConnectionString(
Azure_Storage_Connection_String
);
const containerName = req.user._id;
const ContainerClient = blobServiceClient.getContainerClient(containerName);
try {
const containerResponse = await ContainerClient.create();
} catch (err) {
return res.status(400).send("Error while sending image");
}
res.send("Success in container");
const contentType = file.mimetype;
const filePath = file.path;
const blobName = file.filename + contentType;
const blockBlobClient = ContainerClient.getBlockBlobClient(blobName);
try {
const uploadBlobResponse = await blockBlobClient.uploadFile(filePath);
} catch (err) {
return res.status(400).send("Error while sending image");
}
res.send("Success in Uploading...");
});
module.exports = Router;
You cannot use res.send more than once per request, because one request has only one response. I assume that you want to send a "two-part" response, so that the user first sees "Success in container" and then (a few seconds later) "Success in Uploading ...".
Node.js will send the response in two "chunks" if you use
res.write("Success in container");
...
res.end("Success in Uploading...");
(See also the explanation in this answer.)
I was making CRUD APIs with NodeJS, ExpressJS, and Mongoose, on executing the following code I got an UnhandledPromiseRejectionWarning error for line number 29. Despite having a try-catch block.
Code:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
require('../src/db/conn.js');
const MensRanking = require('../src/models/mens.js');
app.use(express.json());
app.get('/', async (req, res) =>{
res.send("<h1>Hello World!</h1>");
})
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.sendStatus(201).send(insert);
}
catch(e){
res.sendStatus(400).send(e);
}
})
app.get('/mens', async (req, res) =>{
try{
const getMens = await MensRanking.find({});
res.sendStatus(201).send(getMens);
}
catch(e){
res.sendStatus(400).send(e);
}
})
app.listen(port,()=>{
console.log(`\nlistening at http://127.0.0.1:${port}\n`);
})
Error:
(node:20016) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:518:11)
at ServerResponse.header (D:\projects\rest-api-sections\rest-tute\node_modules\express\lib\response.js:771:10)
at ServerResponse.contentType (D:\projects\rest-api-sections\rest-tute\node_modules\express\lib\response.js:599:15)
at ServerResponse.sendStatus (D:\projects\rest-api-sections\rest-tute\node_modules\express\lib\response.js:357:8)
at D:\projects\rest-api-sections\rest-tute\src\app.js:29:13
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:20016) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:20016) [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.
Here is the complete code repository
You should use res.status instead of sendStatus
Difference between response.status() vs. response.sendStatus() in express
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
require('../src/db/conn.js');
const MensRanking = require('../src/models/mens.js');
app.use(express.json());
app.get('/', async (req, res) => {
res.send('<h1>Hello World!</h1>');
});
app.post('/mens', async (req, res) => {
try {
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.status(201).send(insert);
}
catch (e) {
res.status(400).send(e);
}
});
app.get('/mens', async (req, res) => {
try {
const getMens = await MensRanking.find({});
res.status(201).send(getMens);
}
catch (e) {
res.status(400).send(e);
}
});
app.listen(port, () => {
console.log(`\nlistening at http://127.0.0.1:${port}\n`);
});
You are using sendStatus function of epxress.js as it immediately sends that particular assigned code to the response object which triggers response before your data is set, so when your send function is called response object has already been sent, hence the error:
Cannot set headers after they are sent to the client
Instead, use this when you need to set HTTP Response codes as well alongside data
res.status(RESPONSE_CODE).send(DATA)
There are two problematic function in this case i just highlight one, because they have the same errors:
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.sendStatus(201).send(insert);
}
catch(e){
res.sendStatus(400).send(e);
}})
You already sent a response in your try-block with res.sendStatus(201) and trying to send again with .send(insert) -> throws exception
After that you do the same error again with res.sendStatus(400).send(e);
The following code should do what you tried to intend:
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.status(201).send(insert);
}
catch(e){
res.status(400).send(e);
}})
I'm trying to read log file when it's change and emit changes(this part work)
The problem is I get an error :
(node:7088) UnhandledPromiseRejectionWarning: Error: EBUSY: resource busy or locked, open './temp.log'
at Object.openSync (fs.js:457:3)
at new LineByLine (C:\Users\Server\Documents\rconMinecraft\node_modules\n-readlines\readlines.js:23:26)
at myLineReader (C:\Users\Server\Documents\rconMinecraft\node_modules\text-file-diff\index.js:22:15)
at TextFileDiff.diff (C:\Users\Server\Documents\rconMinecraft\node_modules\text-file-diff\index.js:63:25)
at Diff (C:\Users\Server\Documents\rconMinecraft\app.js:56:7)
at Change (C:\Users\Server\Documents\rconMinecraft\app.js:40:3)
at FSWatcher. (C:\Users\Server\Documents\rconMinecraft\app.js:32:7)
at FSWatcher.emit (events.js:321:20)
at FSWatcher.emitWithAll (C:\Users\Server\Documents\rconMinecraft\node_modules\chokidar\index.js:521:8)
at FSWatcher._emit (C:\Users\Server\Documents\rconMinecraft\node_modules\chokidar\index.js:613:10)
(node:7088) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:7088) [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.
I now this error is because the file './temp.log' is already open. I looked for an alternative of my code but I did not find.
My code :
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const express = require('express');
const fs = require('fs');
var chokidar = require('chokidar');
app.use('/public', express.static('public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/views/index.html');
});
var watcher = null;
var _Socket = null;
var path = 'C:/Users/Server/Downloads/Serv/logs/latest.log';
io.sockets.on('connection', function(socket) {
_Socket = socket;
});
WatchFile();
http.listen(80, function() {
console.log('listening on *:80');
});
function WatchFile() {
watcher = chokidar.watch(path, {
persistent: false
});
watcher
.on('change', path => {
Change();
})
}
function Change() {
fs.copyFile(path, './temp.log', (err) => {
console.log('this is a test');
});
Diff();
}
function Diff() {
var TextFileDiff = require('text-file-diff');
var d = new TextFileDiff();
d.on('compared', (line1, line2, compareResult, lineReader1, lineReader2) => { /*console.log(line1 + " ////// " + line2);*/ });
d.on('-', line => {
console.log('File 1 : ' + line);
});
d.on('+', line => {
console.log('File 2 : ' + line);
_Socket.emit('message', line);
});
d.diff(path, './temp.log');
}
I have an existing postgresql database with Rails, now I'm making a Node.js app which is using the same database. I already have users in my db and now I would like to list them all.
I successfully created an express app and then I did as follows:
✗ npm install --save sequelize pg pg-hstore
✗ sequelize init
index.js
const express = require('express');
const logger = require('morgan');
const bodyParser = require('body-parser');
const pg = require('pg');
var conString = 'postgres://localhost:5432/db_name';
var client = new pg.Client(conString);
const app = express();
client.connect(err => {
if (err) {
console.error('connection error', err.stack);
} else {
console.log('connected');
}
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => {
res.send(models.User.findAll);
});
const PORT = process.env.PORT || 5000;
app.listen(PORT);
In my config.json I have:
"development": {
"username": "my_username",
"password": null,
"database": "database_name",
"host": "127.0.0.1",
"dialect": "postgres"
}
I get this error: 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()
I'm probably missing a big step but I don't know what it is, I have never done this before.
Example Query
const query = {
text: 'CREATE TABLE IF NOT EXISTS coverages ('+
'vaccine VARCHAR(64),' +
'country VARCHAR(255),' +
'region VARCHAR(255),' +
'year VARCHAR(4),' +
'value VARCHAR(12),' +
'PRIMARY KEY(vaccine, country, region, year, value))'
};
client.query(query)
.then(function(res) {
console.log(res);
})
.catch(function(err) {
console.log('\nError executing query', err.stack);
});
Here are some example queries using async / await (which requires Node 8+, I believe, so make sure your version supports this):
var express = require('express');
var pg = require('pg');
var router = express.Router();
let conString = 'postgres://localhost:5432/db_name';
var postgrespool = new pg.Pool({
connectionString: conString
});
router.get('/checkdbconnection', function(req, res, next) {
(async () => {
// Here is the query!
// alter it to query a table in your db
// this example just confirms a connection
var { rows } = await postgrespool.query(`
SELECT
'Hello from Postgres' AS pg_val;`);
if (rows.length) {
return res.send(rows);
} else {
res.status(404);
return res.send('No response from database.');
}
})().catch(e =>
setImmediate(() => {
res.status(500);
console.log(e);
return res.send('Error: ' + e.message);
})
);
});
router.get('/checkdbconnection/:name', function(req, res, next) {
let param_name = req.params.name;
(async () => {
// this example demonstrates how to pass parameters to your query with $1, $2, etc.
// usually, the cast of "::text" won't be necessary after the "$1"
var { rows } = await postgrespool.query(`
SELECT
'Hello from Postgres' AS pg_val,
$1::text AS parameter;`, [param_name]);
if (rows.length) {
return res.send(rows);
} else {
res.status(404);
return res.send('No response from database.');
}
})().catch(e =>
setImmediate(() => {
res.status(500);
console.log(e);
return res.send('Error: ' + e.message);
})
);
});
module.exports = router;
If you visit http://localhost:5000/checkdbconnection , you'll get this response:
[
{
"pg_val": "Hello from Postgres"
}
]
And if you visit, say, http://localhost:5000/checkdbconnection/Al-josh , you'll get this:
[
{
"pg_val": "Hello from Postgres",
"parameter": "Al-josh"
}
]
Hopefully my comments in the code have made it clear how the queries work, so you can alter them to your purpose. If not, provide some more detail about your tables and I can amend this answer.
Note also that I am using pg.Pool here to connect to Postgres. This is totally secondary to your question, but the documentation is worth reading.
Using Koa and Koa-router, I write a function to accept POST on /videos and then save the video into HDFS(a distributed database). After the saving process finishing, the response should be sent to client saying that the uploading is finish. However, the response is returned before I/O finsh. I am new for JavaScript, Please help.
app.js:
/**
* Module dependencies.
*/
const logger = require('koa-logger');
const serve = require('koa-static');
const koaBody = require('koa-body');
const Koa = require('koa');
const app = new Koa();
const os = require('os');
const path = require('path');
var Router = require('koa-router');
var router = new Router();
// log requests
app.use(logger());
app.use(koaBody({ multipart: true }));
app.use(serve(path.join(__dirname, '/public')));
app
.use(router.routes())
.use(router.allowedMethods());
// listen
app.listen(3000);
console.log('listening on port 3000');
module.exports ={
app:app,
router:router
}
require('./services/service_upload.js')
service_upload.js
const router = require('../app.js').router
const upload = require('../business/business_uploadVideo.js')
function service_upload() {
router.post('/videos', function (ctx, next) {
upload.upload(ctx, function () {
})
ctx.body='upload finish'
console.log("redirect/")
});
}
service_upload()
If you are using recent versions of Koa and koa-router, then you can use async/await with Promises this way:
router.post('/videos', async function (ctx, next) { // Declare function as async
await new Promise((resolve, reject) => { // Create new Promise, await will wait until it resolves
upload.upload(ctx, function (error) {
if (error) { // Probably you should do error handling
reject(error);
return;
}
resolve();
})
});
ctx.body='upload finish'
console.log("redirect/")
});
More on Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
More on async/await: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await