Running Cypress with MSSQL- timing out - sql-server

I want to clean a database before running my test cases and I'm just having issues with it running. It just times out and I don't understand - hopefully you can help me :)
In the test case I have the following code block:
beforeEach(() => {
cy.task("cleanUpDB", {
sql:"UPDATE SQL GOES HERE"
})
This then goes to my cypress.config file and the following is executed:
on("task", {
cleanUpDB({ theQuery }) {
return new Promise(async(resolve, reject) => {
try{
await sql.connect(DBConfig)
const result = await sql.query(theQuery);
console.log(result)
return resolve(result);
}
catch (err) {
// ... error checks
}
}
)
}
})
This is the error I get in the test runner:

You must use the same property name sql inside the task
beforeEach(() => {
cy.task("cleanUpDB", {
sql:"UPDATE SQL GOES HERE"
})
on("task", {
cleanUpDB({ sql }) { // since you wrap the parameter
... // you must use the property name sql
or just pass in the query directly
beforeEach(() => {
cy.task("cleanUpDB", "UPDATE SQL GOES HERE")
on("task", {
cleanUpDB(theQuery) { // name can be anything
...

Based on the documentation of the library, the below code should work.
const sqlQuery = 'UPDATE SQL GOES HERE';
beforeEach(() => {
cy.task('cleanUpDB', {
sqlQuery,
});
});
// Config file
on('task', {
cleanUpDB({ theQuery }) {
sql.on('error', (err) => {
// Error handling
});
sql
.connect(DBConfig)
.then((pool) => {
return pool.request.query(theQuery);
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
},
});

Related

React Promise All Multiple APIs, Different Error Handling

I wanted to run different error handling with React Promise.
API 1 and 2 should have different error handlings.
Execute APIs all at once to save time.
Run different error handling statements for each API as soon as possible, without waiting for the others.
Each API should continue even if one fails.
How can this be done?
Reference:
Fetch API requesting multiple get requests
Promise.all([
fetch(api1).then(value => value.json()),
fetch(api2).then(value => value.json())
])
.then((value) => {
console.log(value)
//json response
})
.catch((err) => {
console.log(err);
});
Promise.all is just wrapping up whatever promises you give it - so there's no reason you couldn't handle the errors separately for each one. For example, you could create a separate function for each of the fetches - you could even throw a custom error here that dictates some sort of "followUp" action to do, or identifies where the error is from, or anything (you can throw anything in javascript):
const fetchFromApi1 = async () => {
try {
const response = await fetch(api1);
return response.json();
} catch (err) {
console.log('API 1 failed');
// Throw a custom error
throw {
errorSource: 'API_CALL_1',
message: 'API call 1 failed',
};
}
};
const fetchFromApi2 = async () => {
// ----- 8< -----
};
Then you can just combine them in your your Promise.all - if you've thrown a custom error as above, you can use that to work out what to do:
const fetchAllTheThings = async () => {
try {
const [response1, response2] = await Promise.all([
fetchFromApi1(),
fetchFromApi2(),
]);
} catch (err) {
const { errorSource, message } = err;
// do something....
}
};
Edit
If you want to know which promise failed at the point of calling, you're probably better off using allSettled -
const fetchAllTheThings = async () => {
const [result1, result2] = await Promise.allSettled([
fetchFromApi1(),
fetchFromApi2(),
]);
if (result1.status === 'rejected') {
// Sad for promise 1
}
if (result2.status === 'rejected') {
// Sad for promise 2
}
};
const p1 = new Promise((res, rej) => {
setTimeout(() => {
res("p1 success")
}, 1000)
})
const p2 = new Promise((res, rej) => {
setTimeout(() => {
res("p2 success")
}, 3000)
})
const p3 = new Promise((res, rej) => {
setTimeout(() => {
rej("p3 failed")
}, 1000)
})
const p4 = new Promise((res, rej) => {
setTimeout(() => {
rej("p4 failed")
}, 2000)
})
Promise.allSettled([p1, p2, p3, p4])
.then(console.log)

SignalR connect setup in react- using useEffects

I'm using "#microsoft/signalr": "^6.0.5", and trying to set up a connection.
It is able to connect with the backend, but I am not sure if my setup looks OK for when the connection fails.
Specifically, I am wondering if the last useEffect is correctly written (the placement of the onClose clause)
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(
"https://localhost:3000/workorderHub",
{ accessTokenFactory: () => token, withCredentials: false }
)
.configureLogging(LogLevel.Information)
.withAutomaticReconnect()
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
async function start() {
if (connection) {
try {
connection
.start()
.then(() => {
connection.invoke("SubscribeToProject", projectId); // calling hub method from the client
})
.catch((err) => {
console.error(err.toString());
});
connection.on(
"OperationUpdated",
(projectId, operationId, operation) => {
// function called from the backend Hub
actions.updateSyncedOperation({ operationId, operation });
}
);
} catch (err) {
console.log({ err });
setTimeout(start, 5000);
}
} else {
connection.onclose(async () => {
await start();
});
}
}
start();
}, [connection]);
For React 18 with the new strictMode behaviour i do the following.
It only creates one connection without any errors and it seems to cleanup properly during strictmode behaviour.
export const useLiveUpdates = () => {
const [connectionRef, setConnection] = useState < HubConnection > ();
function createHubConnection() {
const con = new HubConnectionBuilder()
.withUrl(`${EnvService.getUrlHub('url')}`, {
accessTokenFactory: () => AuthService.getToken(),
})
.withAutomaticReconnect()
.build();
setConnection(con);
}
useEffect(() => {
createHubConnection();
}, []);
useEffect(() => {
if (connectionRef) {
try {
connectionRef
.start()
.then(() => {
connectionRef.on('message', () => { ...
});
})
.catch((err) => {
logger.error(`Error: ${err}`);
});
} catch (error) {
logger.error(error as Error);
}
}
return () => {
connectionRef ? .stop();
};
}, [connectionRef]);
};

Async line of code is like its invinsible

I dont know much of javaScript and i wanted to make a bot from a youtube tutorial. Now the video said to type this:
(async () => {
try {
if (process.env.ENV === "production") {
await rest.put(Routes.applicationCommands(CLIENT_ID), {
body: commands
});
console.log("Globally");
} else {
if (process.env.ENV === "production") {
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, process.env.GUILD_ID)
, {
body: commands
});
console.log("Locally");
}
}
} catch (err) {
if (err) console.error(err);
}
})
Inside the client.once("ready",
So it turned out something like this:
client.once("ready", () => {
console.log("Bot is online.");
const CLIENT_ID = client.user.id;
const rest = new REST({
version: "9"
}).setToken(process.env.TOKEN);
(async () => {
try {
if (process.env.ENV === "production") {
await rest.put(Routes.applicationCommands(CLIENT_ID), {
body: commands
});
console.log("Globally");
} else {
if (process.env.ENV === "production") {
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, process.env.GUILD_ID)
, {
body: commands
});
console.log("Locally");
}
}
} catch (err) {
if (err) console.error(err);
}
})
});
Now as you can see it says that if it finds client id it should type on console "Locally" to see if it works. But the terminal is like it ignores the whole async it just says that the bot is online nothing for the commands. What did i do wrong
Instead of defining a separate asynchronous function inside the ready handler function, why not just make the ready handler function itself asynchronous? Here's an example:
client.once("ready", async () => {
console.log("Bot is online.");
const CLIENT_ID = client.user.id;
const rest = new REST({
version: "9"
}).setToken(process.env.TOKEN);
try {
if (process.env.ENV === "production") {
await rest.put(Routes.applicationCommands(CLIENT_ID), {
body: commands
});
console.log("Globally");
} else {
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, process.env.GUILD_ID)
, {
body: commands
});
console.log("Locally");
}
} catch (err) {
if (err) console.error(err);
}
});
That should allow the async function to run.
EDIT
Your if statements were slightly incorrect. You are checking if process.env.ENV equals production, and else, you are once again checking if it equals production. I've fixed that in this answer.

This state not updating after a method returns in react

I currently have a class in react. For the sake of saving space I'm only putting the code that is relevant.
this.state = {
orgID: null,
memberID: null,
}
checkAuthUser = () => {
new Promise((resolve, reject) => {
this.props.firebase.auth.onAuthStateChanged(authUser => {
if(authUser) {
console.log(authUser);
resolve(authUser);
} else {
reject(new Error("Not authorized"));
}
})
})
.then( authDetails => {
this.props.firebase.getOrgID().on('value', snapshot => {
const setSnapshot = snapshot.val();
const getOrganizationID = Object.keys(setSnapshot)[0];
this.setState({ memberID: authDetails, orgID: getOrganizationID })
})
})
.catch(err => console.log(err))
}
render() {
if (this.state.orgID == null) {
try {
this.checkAuthUser();
console.log(this.state);
} catch (e) {
console.error(e);
}
}
In the class there's a method checkAuthUser . using firebase it checks whether a user has been signed in or not. If the user is signed in I console.log the object authUser. The console.log does log authUser details so I know it's hitting firebase and then returning the details. After I have a call to get some info from firebase.
I had added some console.logs to also confirm that it was running. However after the data comes back the console.log in render doesn't run anymore. The only console.log I get is the first initial state. What am I missing here?

NodeJs Connection Error querying SQL Server

I am using this code to connect to my SQL Server and retrieve some data which works fine, if I only call the code once. If I call it twice I get this error:
ConnectionError: Already connecting to database! Call close before connecting to different database.at ConnectionPool._connect
But I am closing the conn after the call so I'm not sure what I am missing.
var sql = require('mssql');
const pool = new sql.ConnectionPool({
user: 'sa',
password: 'password',
server: '192.168.1.2',
database: 'demo',
options: {
encrypt: false
}
})
var conn = pool;
module.exports.getCounter = function( query){
conn.connect().then(function (err) {
var req = new sql.Request(conn);
req.query(query).then(function (result) {
console.log(result.recordset);
return result.recordset;
conn.close();
})
.catch(function (err) {
console.log(err);
conn.close();
});
})
.catch(function (err) {
console.log(err);
})};
You're returning the value before closing the connection, hence the function terminates before reaching that line. So just move the return statement below your conn.close(). The other issues you might have afterwards is that you might be calling your function twice before one executes and terminates completely, since those calls are asynchronous.
You might have to set your getCounter function as a Promise, so that you can wait for its completion/failure before calling it again. Off the top of my head in your example:
const getCounter = () => new Promise((resolve,reject) => {
conn.connect().then(function (err) {
var req = new sql.Request(conn);
req.query(query).then(function (result) {
conn.close();
resolve(result);
})
.catch(function (err) {
conn.close();
reject(err);
});
})
})
You can call your function afterwards as getCounter().then((result) => {...})
Here is another way to solve it which might be helpful for others.
const sql = require('mssql')
let connectionPoolConfig = {
user: 'sa',
password: 'password',
server: '192.168.1.2',
database: 'demo',
options: {
encrypt: false
}
}
let connectionPoolPromise = null
let connectionPoolObj = null
let getOrCreatePool = async () => {
if (connectionPoolObj) {
return connectionPoolObj
} else if (!connectionPoolPromise) {
connectionPoolPromise = new sql.ConnectionPool(connectionPoolConfig).connect()
}
connectionPoolObj = await connectionPoolPromise
return connectionPoolObj
}
let query = async(sql) => {
const pool = await getOrCreatePool()
return await pool.request().query(sql)
}
module.exports = {
query: query
}
And here is how to call it
let testCallerSQL = async () => {
try {
const res = await sqlUtil.query('select * from mytable')
console.log(res.recordset)
} catch(err) {
console.log(err)
} finally {
}
}

Resources