Question about forwarding errors from Promise.All to external try … catch - promise

Code:
const promise1 = new Promise((resolve, reject) => {
reject("error promise1");
});
const promise2 = new Promise((resolve, reject) => {
resolve('test promice2')
});
try {
Promise.all([promise1, promise2])
.then(values => {
const [promise1data, promise2data] = values;
console.log(promise1data, promise2data);
})
.catch(error => {
//console.log('error email', error)
throw `ERROR catch1! ${error}`;
});
} catch (err) {
console.log('ERROR catch2', err)
}
Expecting the console output ERROR catch2 and error promise1, but I get:
UnhandledPromiseRejectionWarning
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.

Related

NextJs - Node - API resolved without sending a response for /api/xxx

I have a nextjs app with a backend api where I am sending an email out.
I have seen a couple of other posts with the same issue, have tried their resolutions and not sure what I am missing.
Any insight is appreciated.
The code in the API is below.
const nodemailer = require('nodemailer');
export default function (req, res) {
const mailData = {
from: 'xxxxx',
to: req.body.email,
subject: 'Message to Full On Consulting',
text: req.body.message,
html: '<div>'+req.body.message+'</div>'
}
sendMail(mailData)
.then((result) => {
console.log('Email sent...', result);
res.status(200).json({ status: 'SUCCESS' })
})
.catch((error) => console.log('Error ... ' + error.message));
}
async function sendMail(mailData) {
try {
let transport = nodemailer.createTransport({
host: "mail.xxxxxxxxxx.com",
port: 587,
secure: false,
auth: {
user: process.env.GMAIL_UID,
pass: process.env.GMAIL_PW
}
});
const result = await transport.sendMail(mailData)
return result;
} catch (error) {
console.log("CATCH ERROR: " + error)
return error;
}`enter code here`
}
I wrapped the sendmail call in a promise and that seems to have worked.
var promise = new Promise( (resolve, reject) => {
let result = transport.sendMail(mailData);
});
promise.then( result => {
console.log("PRomise Success ...");
}, function(error) {
console.log("Promise Failure...");
});

How to invoking code sequentially using Promises

I am just starting to learn how to use Promises as I have been experimenting with callbacks so far.
I am trying the code below:
It should invoke promise func1, wait 1 second, check func1's returned value, then invoke promise func2, wait 1 second and then check func2's returned value.
When I run it, I actually get this output:
In func1
func1 sent: 1
func2 sent: undefined
so it is clear the func2 is not being invoked.
Could someone assist a Promis newbie in his first code experiments?
Thank you
class A {
func1(param) {
return new Promise((resolve, reject) => {
// Use param...
console.log("In func1");
setTimeout(() => resolve("1"), 1000);
});
}
func2(param) {
return new Promise((resolve, reject) => {
// Use param...
console.log("In func2");
setTimeout(() => resolve("2"), 1000);
});
}
}
const a = new A();
a.func1("arg1")
.then((value) => {
// Check the value of value returned from func1
console.log("func1 sent: " + value);
}).then((value) => {
// Check the value of value returned from func2
console.log("func2 sent: " + value);
});
I based my code on this. Here there is no explicit call to the 2nd function and it works... Why doesn't it work in solution?
new Promise(function(resolve, reject) {
console.log("In func1");
setTimeout(() => resolve(1), 1000);
}).then(function(value) {
console.log("func1 sent: " + value);
return new Promise((resolve, reject) => {
console.log("In func2");
setTimeout(() => resolve(2), 1000);
});
}).then(function(value) {
console.log("func2 sent: " + value);
});

socket.io client events are not firing

I am trying to run my client without my server connected (on purpose) and catch ERR_CONNECTION_REFUSED error and display it to the user. I read here that this can be achieved using socket events, specifically connect_error
Below in my code, I can never get the events to fire and display the console logs inside. logging this.io.socket prints stuff but none of the events do.. why is that?
$.ajax(args)
.done((msg) => {
this.io.socket.on('connect', msg => {
console.log('connect socket io', msg)
})
resolve(msg);
})
.fail((jqXHR, msg) => {
return new Promise((resolve, reject) => {
console.log('inside promise of fail() - this.io.socket', this.io.socket) // this will log data to console
this.io.socket.on('connect_error', msg => {
console.log('connect_error socket io', msg)
})
this.io.socket.on('connect_failed', (msg) => {
console.log('connect_failed', msg);
});
// return some error here for user
})
});
From what I see, you are attempting to wire up the event handlers only if you get a bad response from your first ajax call. This will not result in any of the socket.io event handlers being initiated.
Move the event handler into the code where you initialize the socket instance.
See below for a full example where all the manager and socket events will be logged to console.
$.ajax(args)
.done((msg) => {
// connect to your server
const socket = io('http://localhost:3000', {
transports: ['websocket']
});
// manager events
//_________________________________________________________________________________________________
socket.io.on('connect_error', (err) => {
console.error(`manager:connect_error ${err}`);
});
socket.io.on('connect_timeout', () => {
console.error(`manager:connect_timeout`);
});
socket.io.on('reconnect_attempt', (attempt) => {
console.error(`manager:reconnect_attempt ${attempt}`);
});
socket.io.on('reconnecting', (attempt) => {
console.error(`manager:reconnecting ${attempt}`);
});
socket.io.on('reconnect_error', (err) => {
console.error(`manager:reconnect_error ${err}`);
});
socket.io.on('reconnect_failed', () => {
console.error(`manager:reconnect_failed`);
});
//_________________________________________________________________________________________________
// socket events
//_________________________________________________________________________________________________
socket.on('connect', () => {
console.log(`socket:connect ${socket.connected}`);
});
socket.on('connect_error', (err) => {
console.error(`socket:connect_error ${err}`);
});
socket.on('connect_timeout', (timeout) => {
console.error(`socket:connect_timeout ${timeout}`);
});
socket.on('error', (err) => {
console.error(`socket:error ${err}`);
});
socket.on('disconnect', (reason) => {
console.info(`socket:disconnect ${reason}`);
if (reason === 'io server disconnect') {
// the disconnection was initiated by the server, you need to reconnect manually
socket.connect();
}
// else the socket will automatically try to reconnect
});
socket.on('reconnect', (attempt) => {
console.error(`socket:reconnect ${attempt}`);
});
socket.on('reconnect_attempt', (attempt) => {
console.error(`socket:reconnect_attempt ${attempt}`);
});
socket.on('reconnecting', (attempt) => {
console.error(`socket:reconnecting ${attempt}`);
});
socket.on('reconnect_error', (err) => {
console.error(`socket:reconnect_error ${err}`);
});
socket.on('reconnect_failed', () => {
console.error(`socket:reconnect_failed`);
});
//_________________________________________________________________________________________________
// custom events
//_________________________________________________________________________________________________
socket.on('hello', (message) => {
console.info(message);
socket.emit('hello', {foo: 'baz'});
});
//_________________________________________________________________________________________________
resolve(msg);
})
.fail((jqXHR, msg) => {
console.error(msg);
});

How to get rid of 'return new Promise' and not to lose data?

In this case, there is nothing easier to wait until the data is received, and then resolve the Promise:
// Using Promise resolve/reject
module.exports = () => {
return new Promise(async (resolve, reject) => {
let doc = await Document();
doc.on('data', async (data) => {
resolve(data);
});
})
}
But what do I do in this case?
// Using async/await
module.exports = async () => {
let doc = await Document();
doc.on('data', (data) => {
// ???
});
}
You still need the new Promise, you just should use it as the operand of an await inside the async function, not using an async function as the executor:
module.exports = async () => {
const doc = await Document();
return new Promise(resolve, reject) => {
doc.on('data', resolve);
});
};
However, I would recommend to use once instead of on so that the event handler is removed after the first occurrence of the event - the promise can be resolve only once anyway. Also if you have node v11.13.0 or higher you can just use the events.once method so that you don't have to build the promise yourself - and it also handles error events correctly:
const { once } = require('events');
module.exports = async () => {
const doc = await Document();
return once(doc, 'data');
};

Timeout error when using promises with mocha and chai when `should` expectation fails [duplicate]

This question already has answers here:
node.js how to get better error messages for async tests using mocha
(2 answers)
Closed 5 years ago.
While writing tests for a project with Mocha & Chai I noticed I could get true.should.be.false to fail, but when the variable under test came from a promise and that expectation failed, Mocha would time out: Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
Here are the examples of things I tried (and the solution) in hopes that it'll help someone in the future.
const chai = require('chai');
const should = chai.should();
const assert = chai.assert;
function getFoo() {
return new Promise((resolve, reject) => {
resolve({bar: true});
});
}
describe('Example for StackOverflow', function() {
it('will fail as expected', function() {
true.should.be.false;
});
it('will also fail as expected', function() {
var foo = {
bar: true
};
foo.bar.should.be.false;
});
it('times out instead of fails', function(done) {
getFoo().then(data => {
data.bar.should.be.false;
done();
});
});
it('times out instead of fails even without arrow notation', function(done) {
getFoo().then(function(data) {
data.bar.should.be.false;
done();
});
});
it('should throws an error when the expectation fails, but the done() in catch() doesnt seem to matter', function(done) {
getFoo().then(data => {
data.bar.should.be.false;
done();
})
.catch(error => {
console.error(error);
done();
})
.catch(error => {
console.error(error);
done();
});
});
it('still throws an error in the catch() if I try to use assert.fail() inside the catch to force a failure', function(done) {
getFoo().then(data => {
data.bar.should.be.false;
done();
})
.catch(error => {
console.error(error);
assert.fail(0, 1);
done();
})
.catch(error => {
console.error(error);
done();
});
});
});
For reference, here are the versions at play here:
node: v5.12.0
chai: v4.1.0
mocha: v3.4.2
This is different from node.js how to get better error messages for async tests using mocha in that I'm specifically talking about a timeout that occurs when should detects a failure and throws an error that isn't caught because the promise is not returned. Their solution focuses on using done- mine does not need it because it's returning the promise to Mocha so that it can catch the error.
The solution is to return the promise in the test function - I wasn't doing that in my times out instead of fails examples, and I noticed it later while writing up my examples to ask this question.
const chai = require('chai');
const should = chai.should();
const assert = chai.assert;
function getFoo() {
return new Promise((resolve, reject) => {
resolve({bar: true});
});
}
describe('Example for StackOverflow', function() {
it('needs to return the promise for the test runner to fail the test on a thrown exception - no done necessary', function() {
return getFoo().then(data => {
data.bar.should.be.false;
});
});
});

Resources