**Hello, please do you know how can I send message to client via socket when I have error in my SQl query on server side ? **
Server side
io.on('connect', (socket) => {
console.log("User connected: " + socket.id);
socket.on('disconnet', () => {
console.log("disconnected");
})
.post('/addDiel', (req, res) => { //Pridanie dielu do DB
pool.getConnection((err, connection) => {
if(err) throw err
console.log(`Pripojene ako ID ${connection.threadId}`)
const params = req.body;
res.send({
MenoDielures: params.MenoDielu,
DruhDielures: params.DruhDielu,
ProjektNameres: params.ProjektName
})
ProjektNameDB = params.ProjektName.split('.').join("_");
connection.query('INSERT INTO `Skener_db`.`?` (`MenoDielu`, `DruhDielu`, `DatumCas`) VALUES (?, ?, NOW())', [ProjektNameDB, params.MenoDielu, params.DruhDielu],(err, rows)=> {
connection.release()
if(!err) {
res.send(console.log(`Hodnota ${params.MenoDielu} bola pridana.`))
} else {
console.log(err);
if (err.code == ('ER_DUP_ENTRY')) {
//send message to client
}
//res.send({alertMessage: 'Diel už bol oskenovaný. Oskenuj ďaľší.'})
}
})
console.log(req.body)
})
})
})
My client side:
socket.on('connect', () => {
$('#skuska').html("Socket pripojeny");
})
socket.on('receiveDUPmessage', message => {
$('#skuska').html(message);
})
The code here is just for example. I didnt find solution for my problem, so I'm asking here
You have to emit events and socket is locally scoped. io.sockets is not, So you can do it like this on the server-side:
if(!err) {
res.send(console.log(`Hodnota ${params.MenoDielu} bola pridana.`))
} else {
console.log(err);
if (err.code == ('ER_DUP_ENTRY')) {
//send message to client
io.sockets.emit('my error', 'Some error happened');
}
//res.send({alertMessage: 'Diel už bol oskenovaný. Oskenuj ďaľší.'})
}
And on the client-side do this:
socket.on('my error', function (text) {
console.log(text);
});
Here is some sort of posts that may help you:
How to emit error to be possible catch it on error handler on client-side?
How to emit a socket.io response within post request in NodeJS
Related
I have a tcp socket client connection and server in my app. My main goal is taking data from server and send it to client connection. It works great while my app is running but if i get app to background it just sends one data and sends other datas after opening app again. I tried expo-task-manager but it just sends first data and doesnt sends after it as before. I was using my function inside useEffect in a context component. My function with task manager is below.
const BACKGROUND_CLIENT_TASK = "background-client-task";
TaskManager.defineTask(BACKGROUND_CLIENT_TASK, async () => {
const now = Date.now();
console.log(
`Got background fetch call at date: ${new Date(now).toISOString()}`
);
const mainFunction = async () => {
const server = TcpSocket.createServer(function (socket) {
socket.on("data", (takenData) => {
const jsonStringData = String.fromCharCode(...takenData);
const data = JSON.parse(jsonStringData);
const clientOptions = {
port: 1500,
host: "localhost",
};
const dataToClientArray = [
`DataProcess1${data}`,
`DataProcess2${data}`,
`DataProcess3${data}`,
];
dataToClientArray.forEach((dataToClient, index) => {
setTimeout(() => {
const client = TcpSocket.createConnection(
clientOptions,
() => {
// Write on the socket
client.write(`${dataToClient}`, "hex");
console.log("client started");
console.log(dataToClient);
// Close socket
client.destroy();
}
);
client.on("data", (data) => {
console.log("Received: ", data.toString());
});
client.on("error", (error) => {
console.log("Error: ", error);
});
client.on("close", () => {
console.log("Connection closed");
});
}, 300 * index);
});
});
socket.on("error", (error) => {
console.log("An error ocurred with client socket ", error);
});
socket.on("close", (error) => {
console.log("Closed connection with ", socket.address());
});
}).listen({ port: 1754, host: "0.0.0.0" });
server.on("error", (error) => {
console.log("An error ocurred with the server", error);
});
server.on("close", () => {
console.log("Server closed connection");
});
};
mainFunction();
// Be sure to return the successful result type!
return BackgroundFetch.BackgroundFetchResult.NewData;
});
BTW It doesnt start if i dont add the mainFunction in useEffect
The code that i register my defined Task. (result returns undefined)
async function registerBackgroundFetchAsync() {
return BackgroundFetch.registerTaskAsync(BACKGROUND_CLIENT_TASK, {
minimumInterval: 5, // seconds
stopOnTerminate: false, // android only,
startOnBoot: true, // android only
});
}
const registerFunction = async () => {
const result = await registerBackgroundFetchAsync();
console.log(result);
console.log("resultup");
const status = await BackgroundFetch.getStatusAsync();
const isRegistered = await TaskManager.isTaskRegisteredAsync(
BACKGROUND_CLIENT_TASK
);
setStatus(status);
setIsRegistered(isRegistered);
};
registerFunction();
I am trying to catch an error whilst the user tries to access a page without an authentication token.
axios.js?v=012beb2f:840 POST http://localhost:3001/api/get-user 422 (Unprocessable Entity)
Uncaught (in promise) AxiosError {message: 'Request failed with status code 422', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
router.beforeEach((to, from, next) => {
const store = useUserStore()
if(to.meta.requiresAuth)
{
try
{
const response = axios.post('/api/get-user', {}, {
headers: {
Authorization: `Bearer ${store.user.token}`
}
})
.then(response => {
console.log(response)
next()
})
}
catch(error)
{
console.log(error)
next('/login')
}
}
else
{
next()
}
})
Thats the code that makes the request to the server. If the token is correct it works fine. However incorrect token throws the error mentioned above. I would like it to redirect to /login page if token is incorrect.
This is the code on server side.
router.post('/get-user', signupValidation, (req, res, next) => {
if(
!req.headers.authorization ||
!req.headers.authorization.startsWith('Bearer') ||
!req.headers.authorization.split(' ')[1]
){
return res.status(422).json({
message: "Please provide the token",
});
}
const theToken = req.headers.authorization.split(' ')[1];
const decoded = jwt.verify(theToken, 'the-super-strong-secrect');
db.query('SELECT * FROM users where id=?', decoded.id, function (error, results, fields) {
if (error) throw error;
return res.send({ error: false, data: results[0], message: 'Fetch Successfully.' });
});
});
Change the synchronous try/catch...
try
{
somePromise.then(...)
}
catch(error)
{
console.log(error)
next('/login')
}
...to instead use the catch() provided by the promise:
const headers = { Authorization: `Bearer ${store.user.token}` };
axios.post('/api/get-user', {}, { headers })
.then(response => {
console.log(response)
next()
})
.catch(error => {
console.log(error)
next('/login')
}}
Note, also, that the OP code incorrectly assigned the axios.post promise to an unused variable called "response".
Alternatively, use the synchronous try/catch style with async/await:
router.beforeEach(async (to, from, next) => {
const store = useUserStore()
if(to.meta.requiresAuth)
{
try
{
const headers = { Authorization: `Bearer ${store.user.token}` };
const response = await axios.post('/api/get-user', {}, { headers });
console.log(response);
next();
}
catch(error)
{
console.log(error)
next('/login')
}
}
else
{
next()
}
})
I went through several SO threads regarding this. Didn't work anything. But my case is different. In my case, nothing happens. Here is the code:
import amqplib from 'amqplib'
const AMQP_URL = 'amqp://guest:guest#localhost:5672/'
const AMQP_QUEUE_NAME = 'email_queue'
function connectRabbitMQ() {
console.log('Connecting to rabbit mq...')
amqplib.connect(AMQP_URL, async (err: Error, connection: amqplib.Connection) => {
if (err) {
console.log('This log doesn\'t print')
throw err
}
console.log('This log doesn\'t print')
// Listener
const channel1 = await connection.createChannel()
channel1.consume(AMQP_QUEUE_NAME, (msg) => {
if (msg !== null) {
console.log('Recieved:', msg.content.toString());
channel1.ack(msg);
} else {
console.log('Consumer cancelled by server');
}
})
// Sender
const channel2 = await connection.createChannel()
setInterval(() => {
channel2.sendToQueue(AMQP_QUEUE_NAME, Buffer.from('something'))
}, 1000)
})
}
function launchServer() {
console.log('Launching Server...')
console.log('Connecting to MongoDB...')
const MONGODB_URI = process.env.MONGODB_URI?.toString() || ''
mongoose.connect(MONGODB_URI, {}, (err) => {
if (err) {
return console.error('Error connecting to Mongo DB !')
}
console.log('CONNECTED TO MONGO DB')
const port = parseInt(process.env.PORT?.toString() || '3000')
app.listen(port)
console.log('========= SERVER STARTED ========== PORT ' + port)
connectRabbitMQ()
})
}
launchServer()
Neither error nor success occur. The log doesn't get printed. Last log get printed is - Connecting to rabbit mq...
function connectRabbitMQ doesn't seems to be executed.
try appending this on last line of your code
connectRabbitMQ();
I am implementing a JWT authentication on a login/registration system. When there is a successful login/registration I am setting a user token in localStorage.
Problem is when I check my localStorage the user key is present but the value is undefined. I think the issue might be in my axios post or in my express file but I can't quite figure it out.
// my action creator
export function login(user, history) {
return async (dispatch) => {
axios.post('/api/login', { user })
.then(res => {
dispatch({ type: AUTHENTICATED });
localStorage.setItem('user', res.data.token);
history.push('/');
})
.catch((error) => {
dispatch({
type: AUTHENTICATION_ERROR,
payload: 'Invalid email or password'
});
});
};
}
The data is reaching my api correctly. The item is being set but the value res.data.token is undefined.. Below is my express file
// login.js (/api/login)
router.post('/', function(req, res) {
var email = req.body.user.email;
var password = req.body.user.password;
// TODO: create db file and import connection
var connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "dbname",
port: 3307
});
connection.connect(function(err) {
if(err) {
console.log(err);
} else {
connection.query("SELECT ID, Password FROM Users WHERE Email = ?", [email], function(err, result) {
if(err) {
console.log('Could not find account');
res.send(err);
} else {
var id = result[0].ID;
bcrypt.compare(password, result[0].Password, function(err, result) {
if(result) {
console.log(id);
res.json({ id });
} else {
console.log('Incorrect password');
}
});
}
});
}
});
});
Since the res.data.token in my action creator is returning undefined does that mean the response in my express file ( res.json([id]) ) is just returning defined?
You are not sending the response properly.
res.json([id]); Its just sending the array of id. That's why res.data.token is undefined. as data does not contain an object.
Send proper object like:
res.json({id});
i am getting error in npm mssql 3.0.0 with sqlserver 2012
i am creating single page application where i used restful using express .
there are 4 method which executing the query and returning the data to response.
for each method i am opening the connection and closing the connection.
but when savedquery is calling then connection close error occurs.
each method code is similar to savedquery method (copy pasted code only queries are changed) but they are executing savedquery is not executing
{ [ConnectionError: Connection is closed.]
name: 'ConnectionError',
message: 'Connection is closed.',
code: 'ECONNCLOSED' }
var savedquery=function(req,res){
dbConfig= {
user: 'XXX',
password: 'XXXXXXXXXX',
server: 'localhost', // You can use 'localhost\\instance' to connect to named instance
database: 'DEMO_ODS',
options: {
encrypt: true
}
};
sql.connect(dbConfig).then(function (err) {
var sqlrequest = new sql.Request();
sqlrequest.query("SELECT * from SavedQuery").then(function (recordset) {
sql.close(function (value) {
console.log("connection6 closed");
});
return res.status(200).send(recordset);
}).catch(function (err) {
console.log(err);
});
}).catch(function (err) {
console.log(err);
});
};
}
I know it is an old questionm but this answer is for the others who are facing the same isue. I had the same problem, What I did is, used promises as below.
function getData() {
try {
sqlInstance.connect(setUp)
.then(function () {
// Function to retrieve all the data - Start
new sqlInstance.Request()
.query("select * from Course")
.then(function (dbData) {
if (dbData == null || dbData.length === 0)
return;
console.dir('All the courses');
console.dir(dbData);
})
.catch(function (error) {
console.dir(error);
});
// Function to retrieve all the data - End
// To retrieve specicfic data - Start
var value = 1;
new sqlInstance.Request()
.input("param", sqlInstance.Int, value)
.query("select * from Course where CourseID = #param")
.then(function (dbData) {
if (dbData == null || dbData.length === 0)
return;
console.dir('Course with ID = 1');
console.dir(dbData);
})
.catch(function (error) {
console.dir(error);
});
// To retrieve specicfic data - End
}).catch(function (error) {
console.dir(error);
});
} catch (error) {
console.dir(error);
}
}
This solved my issue. You can find the fix here.
You should remove
options: {
encrypt: true
}
from your dbConfig
I just use promise to handle concurrent request:
const executeQuery = function (res, query, dbName) {
dbConfig = {
user: "********",
password: "********",
server: "*******",
database: dbName
}
sql.connect(dbConfig).then(pool => {
return pool.request().query(query)
}).then(result => {
res.send(result);
}).catch(err => {
res.send(err);
});
}
Hope it's help someone.