SYSTEM_ERROR: system encountered unexpected error. Function killed. Cloud functions - node.js

When I looked through logs from Firebase cloud functions, I noticed that some functions have an error in logs with a description of "SYSTEM_ERROR: system encountered unexpected error. Function killed.", Until yesterday, this behavior was not, here is one of these functions. How can I fix it?
const functions = require('firebase-functions');
const admin = require('firebase-admin');
module.exports = functions.database.ref('/cards/{cardID}/interestedUsers').onWrite(event => {
const cardID = event.params.cardID;
console.log("interestedUsers", event.data.val(), cardID);
var currentInterestedUsers = [];
currentInterestedUsers = event.data.val();
var previousInterestedUsers = [];
previousInterestedUsers = event.data.previous.val();
if (event.data.previous.val() && currentInterestedUsers) {
var isNewPendingRequest = false;
if (currentInterestedUsers.length < previousInterestedUsers.length) {
currentInterestedUsers.forEach((interestedUser, index) => {
const interestedUserVal = interestedUser.val();
const isApproved = interestedUser["isApproved"];
console.log("result", interestedUser.val(), interestedUserVal);
if (isApproved == false) {
isNewPendingRequest = true;
}
});
}
if (isNewPendingRequest == false) {
const cardRef = admin.database().ref("cards").child(cardID);
const setupIsNewPendingRequestPromise = cardRef.update({
"isNewPendingRequest": false
});
return Promise.all([setupIsNewPendingRequestPromise]);
};
return console.log("interestedUsers deleting");
};
if (event.data.val() == null) {
console.log("event.data.val() == null");
const cardRef = admin.database().ref("cards").child(cardID);
// check card
const cardCheckPromise = cardRef.once("value", function(cardCheckPromiseSnap, error){
if (error) {
return console.log("cardCheckPromise", error);
};
if (cardCheckPromiseSnap.val()) {
const checkCardID = cardCheckPromiseSnap.val()["id"];
if (checkCardID) {
console.log("checkCardID", checkCardID);
const setupIsNewPendingRequestPromise = cardRef.update({
"isNewPendingRequest": false
});
return Promise.all([setupIsNewPendingRequestPromise]);
} else {
return console.log("checkCardID == null");
}
} else {
return console.log("cardCheckPromiseSnap.val() == null");
};
});
return Promise.all([cardCheckPromise]).catch(function(cardCheckPromiseError){
console.log("cardCheckPromise error", cardCheckPromiseError.message, cardCheckPromiseError.messageId)
});
}
return console.log("just update or adding a new interested user");
});

You can try re-deploying your app.

Likely a GCF outage. There was one today and yesterday. These errors were being thrown during the outage.
Solution
Take a break and wait for the cloud to heal. Contact GCP Support if you've purchased support.

Related

Why latest updated sha is coming when using github api in switch case

I am doing file update operations using GitHub API. For example, let's say I am having a file called App.js and i am updating first line. While updating I will pass the sha.
When i am trying to update another line in the same file, the new updated sha is not coming, the older sha is coming. I am not doing all these steps manually, I have written code for all these operations. Let me paste the code for understanding,
var cosmos = [
{
"_id":"63773144c3160f782c087e35",
"nfrid":"637328ebf5c4b2558b064809",
"nfrname":"azuread",
"fileName":"index.js",
"isImport":true,
"isConst":false,
"isComponent":false,
"isNewFile":false,
"isPackage":false,
"landmark":null,
"isAfter":null,
"fileContent":"import { MsalProvider } from '#azure/msal-react';import { msalConfig } from './authConfig';import {PublicClientApplication } from '#azure/msal-browser';",
"filePath":"src/index.js",
"isIndexHtml":false,
"projecttypeid":"6372366d1b568e00d8af2e44",
"projecttypetitle":"PWA React",
"isReplace":false
},
{
"_id":"637731a2c3160f782c087e37",
"nfrid":"637328ebf5c4b2558b064809",
"nfrname":"azuread",
"fileName":"index.js",
"isImport":false,
"isConst":false,
"isComponent":true,
"isNewFile":false,
"isPackage":false,
"landmark":"<App />",
"isAfter":null,
"fileContent":"<MsalProvider instance={msalInstance}><App /></MsalProvider>",
"filePath":"src/index.js",
"isIndexHtml":false,
"projecttypeid":"6372366d1b568e00d8af2e44",
"projecttypetitle":"PWA React",
"isReplace":true,
}
];
for (let i = 0; i < cosmos.length; i++) {
switch (true) {
case cosmos[i].isImport:
const statusImport = common.updateImport(cosmos[i]);
console.log(statusImport);
break;
case cosmos[i].isConst:
const statusConst = common.updateConst(cosmos[i]);
console.log(statusConst);
break;
case cosmos[i].isPackage:
const statusPackage = common.updatePackage(cosmos[i]);
console.log(statusPackage);
break;
case cosmos[i].isIndexHtml:
const statusIndexHtml = common.updateIndexHTML(cosmos[i]);
console.log(statusIndexHtml);
break;
case cosmos[i].isNewFile:
const statusNewFile = common.addNewFile(cosmos[i]);
console.log(statusNewFile);
break;
case cosmos[i].isComponent:
const statusComponent = common.updateComponent(cosmos[i]);
console.log(statusComponent);
break;
default:
console.log("Nothing to add/update");
break;
}
}
I will be updating both these things in index.js file only. But the first thing is getting updated properly, when the second thing comes, it shows error like "src/index.js does not match with sha-id". I checked , that sha id is not the updated one, it changes after first update happens and i am getting that error . i will also paste my code logic which i wrote for updating files.
async function updateImport(cosmos) {
let temp = cosmos.filePath;
let newSha = "";
let newContent = "";
let decodedContent = "";
const octokit = new Octokit({
auth: "ghp_auth-token"
});
try {
return await new Promise(async (resolve, reject) => {
const response = await octokit.request(
`GET /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`
);
newSha = response.data.sha;
decodedContent = atob(response.data.content);
if (cosmos.isImport === true) {
newContent = cosmos.fileContent + decodedContent;
}
let encodedContent = Buffer.from(newContent).toString("base64");
const update = await octokit.request(
`PUT /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`,
{
message: "Updating import statements",
content: encodedContent,
sha: newSha
}
);
console.log(update.status);
resolve("success");
});
} catch (error) {
console.log(error);
}
}
async function updateComponent(cosmos) {
let temp = cosmos.filePath;
let newSha = "";
let newContent = "";
let decodedContent = "";
const octokit = new Octokit({
auth: "ghp_auth token"
});
try {
return await new Promise(async (resolve, reject) => {
const response = await octokit.request(
`GET /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`
);
newSha = response.data.sha;
decodedContent = atob(response.data.content);
if (cosmos.isComponent === true) {
if (cosmos.isAfter === false) {
newContent = decodedContent.replace(
cosmos.landmark,
cosmos.fileContent + cosmos.landmark
);
} else if(cosmos.isAfter === true) {
newContent = decodedContent.replace(
cosmos.landmark,
cosmos.landmark + cosmos.fileContent
);
}
else if (cosmos.isReplace === true) {
newContent = decodedContent.replace(
cosmos.landmark,
cosmos.fileContent
);
}
}
// var formattedContent = prettier.format(newContent,{ semi: false, parser: "mdx" });
let encodedMDContent = Buffer.from(newContent).toString("base64");
const update = await octokit.request(
`PUT /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`,
{
message: "Updating components",
content: encodedMDContent,
sha: newSha
}
);
console.log(update.status);
resolve("success");
});
} catch (error) {
console.log(error);
}
}
i need to know why the latest updated sha id is not coming when the second update is happening.
I need to know if the problem is with switch case or the new updated sha will not come in the second update function.

connection.queryRaw is not a function error in NodeJs WebAPI call

I am new to Nodejs. I am developing WebAPI by using NodeJs and MSSQl as database.My api is giving proper response in case of POST endpoint If it is called while server is listening through Dev environment command [npm run start]. But, If I Deploy my API on Windows IIS , it is giving the mentioned error. My reference API endpoint code is as below :
router.post('/',async (req,res,next)=>{
// console.log('Enter products creation')
const Product = Array.from(req.body) // req.body
// console.log('New Product details passed on',Product)
const createProd = require('../CreateProduct')
const response = await createProd(Product)
res.status(404).json({
message : response.retStatus
})
})
CreateProduct function called in above code is as below :
const sql = require("mssql/msnodesqlv8");
const dataAccess = require("../DataAccess");
const fn_CreateProd = async function (product) {
let errmsg = "";
let objBlankTableStru = {};
let connPool = null;
// console.log('Going to connect with Connstr:',global.config)
await sql
.connect(global.config)
.then((pool) => {
global.connPool = pool;
productsStru = pool.request().query("DECLARE #tblProds tvp_products select * from #tblProds");
return productsStru;
})
.then(productsStru=>{
objBlankTableStru.products = productsStru
productsOhStru = global.connPool.request().query("DECLARE #tblprodsOh tvp_product_oh select * from #tblprodsOh");
return productsOhStru
})
.then((productsOhStru) => {
objBlankTableStru.products_oh = productsOhStru
let objTvpArr = [
{
uploadTableStru: objBlankTableStru,
},
{
tableName : "products",
tvpName: "tvp_products",
tvpPara: "tblProds"
},
{
tableName : "products_oh",
tvpName: "tvp_product_oh",
tvpPara: "tblProdsOh",
}
];
newResult = dataAccess.getPostResult(
objTvpArr,
"sp3s_ins_products_tvp",
product
);
console.log("New Result of Execute Final procedure", newResult);
return newResult;
})
.then((result) => {
// console.log("Result of proc", result);
if (!result.recordset[0].errmsg)
errmsg = "New Products Inserted successfully";
else errmsg = result.recordset[0].errmsg;
})
.catch((err) => {
console.log("Enter catch of Posting prod", err.message);
errmsg = err.message;
if (errmsg == "") {
errmsg = "Unknown error from Server... ";
}
})
.finally((resp) => {
sql.close();
});
return { retStatus: errmsg };
};
module.exports = fn_CreateProd;
GetPost() function is as below :
const getPostResult = (
tvpNamesArr,
procName,
sourceData,
sourceDataFormat,
singleTableData
) => {
let arrtvpNamesPara = [];
let prdTable = null;
let newSrcData = [];
// console.log("Source Data :", sourceData);
let uploadTable = tvpNamesArr[0];
for (i = 1; i <= tvpNamesArr.length - 1; i++) {
let tvpName = tvpNamesArr[i].tvpName;
let tvpNamePara = tvpNamesArr[i].tvpPara;
let TableName = tvpNamesArr[i].tableName;
let srcTable = uploadTable.uploadTableStru[TableName];
srcTable = srcTable.recordset.toTable(tvpName);
let newsrcTable = Array.from(srcTable.columns);
newsrcTable = newsrcTable.map((i) => {
i.name = i.name.toUpperCase();
return i;
});
if (!singleTableData) {
switch (sourceDataFormat) {
case 1:
newSrcData = sourceData.filter((obj) => {
return obj.tablename.toUpperCase() === TableName.toUpperCase();
});
break;
case 2:
newSrcData = getObjectDatabyKey(sourceData, TableName);
break;
default:
newSrcData = getTableDatabyKey(sourceData, TableName);
break;
}
} else {
newSrcData = sourceData;
}
// console.log(`Filtered Source data for Table:${TableName}`, newSrcData);
prdTable = generateTable(
newsrcTable,
newSrcData,
tvpName,
sourceDataFormat
);
arrtvpNamesPara.push({ name: tvpNamePara, value: prdTable });
}
const newResult = execute(procName, arrtvpNamesPara);
return newResult;
};
Finally, I have found the solution to this.. it is very strange and shocking and surprising that If I using Morgan Middleware in app.js and have used it by syntax : app.use(morgan('dev')) , then it is the culprit command..I just removed dev from this command after which problem got resolved..But I found no help regarding this issue over Google anywhere..I really fear that what type of challenges I am going to face in future development if these kind of silly error come without giving any hint..I would be highly obliged If anyone could make me understand this kind of silly errors..

Best practice using promises chaining in node JS

I'm little bit confusing in promises. first, I have some ugly code like this:
async function presence(ctx) {
try {
var prsenceData = [];
var isSuccess = Boolean(false);
var ckFilePath = "./somepath/cookie.json";
if (!fs.existsSync(ckFilePath)) {
await menuLogin.login(ctx).then(login => {
isSuccess = Boolean(login[0].status);
myCk.saveCookies(login[0].cookies, ckFilePath);
if (!isSuccess) {
myCk.deleteCookies(ckFilePath);
return false;
}
});
} else {
await myCk.checkToDelete(ckFilePath).then(isDel => {
if (isDel) {
return false;
}
});
}
await presenceNow.check(fs.existsSync(ckFilePath), ctx).then(data => {
for (let id = 0; id < data[0].pesan.length; id++) {
console.log(data[0].pesan[id]);
}
for (let id = 0; id < data[0].id.length; id++) {
presenceData.push(data[0].id);
}
if (data[0].pesan.length == 0 && fs.existsSync(ckFilePath)) {
myCk.deleteCookies(ckFilePath);
}
});
} catch (e) {
console.log(e);
}
return presenceData;
}
Can anyone explain why presenceNow.check() function is not calling if my ckFilePath does not exist? but if myCkFilePath is exist, my code run so well. And maybe anyone can show me the better code for that case? thanks.
Mixing async/await and promise chains like this is something of a code smell that the author lacked an understand of async/await. It's also something of a mixed metaphor.
If you refactor it to actually use async/await you get something like this that's a lot easier to understand.
My suspicion is that your presenceNow.check() method is not being called because the function is taking returning via one of the two return paths above it:
the file exists and myCk.checkToDelete() returns true, or
the file does not exist, and the login is unsuccessful.
const fs = require('fs/promises');
async function presence(ctx) {
var presenceData = [];
var isSuccess = false;
var ckFilePath = "./somepath/cookie.json";
let ckFilePathExists = await fs.access(ckFilePath);
if (ckFilePathExists) {
const isDel = await myCk.checkToDelete(ckFilePath);
if (isDel) {
return false;
}
} else {
const login = await menuLogin.login(ctx);
const isSuccess = login[0].status
myCk.saveCookies(login[0].cookies, ckFilePath);
if (!isSuccess) {
myCk.deleteCookies(ckFilePath);
return false;
}
}
ckFilePathExists = await fs.access(ckFilePath)
const data = await presenceNow.check(ckFilePathExists, ctx);
for (let id = 0; id < data[0].pesan.length; id++) {
console.log(data[0].pesan[id]);
}
for (let id = 0; id < data[0].id.length; id++) {
presenceData.push(data[0].id);
}
if (data[0].pesan.length == 0 && await fs.access(ckFilePath) ) {
myCk.deleteCookies(ckFilePath);
}
return presenceData;
}

Fetch API Doesn't send data on first call - NestJs

I have an API in NestJs which is not sending data on the first hit. However, on hitting it again it sends the desired data. I am guessing the API returns before the internal processing is done.
How to stop this. Is sleep a good option for this?
Or is there any other way to do this?
#Post("load")
#UseGuards(AuthGuard("jwt"))
async load(#Req() body: any)
{
const organizationId = body.user.organizationId;
const userId = body.user.userId;
if ("brandIds" in body.body)
{
await this.userService.onBoardUser(userId);
}
var settings = await this.settingsService.fetchLayout(organizationId, "home");
settings.forEach(async (element) =>
{
var parsedElement = JSON.parse(JSON.stringify(element));
var innerContent = await this.fetchContent(parsedElement.method, organizationId, userId);
var template = parsedElement.content[0];
let formattedItem = {};
innerContent.forEach((item) =>
{
try
{
formattedItem = template;
Object.keys(template).forEach((key) =>
{
if (template[key]!= "" && key != "type")
{
formattedItem[key] = eval(template[key]);
}
});
parsedElement.content.push(formattedItem);
formattedItem = null;
}
catch(err)
{
}
});
this.response.data.push(parsedElement);
innerContent = null;
template = null;
formattedItem = null;
parsedElement = null;
});
return(this.response);
}
looks like your main problem here is that your using async/await inside foreach which isnt working.
Use it like this:
for (const setting of settings) {
... your async code here.
}

ESOCKETTIMEDOUT Cloud Functions for Firebase

I am using Cloud Functions for Firebase together with my Firebase Realtime Database in order to do some data management for my app.
One of my functions though seems to get terminated since it takes about 100-150 seconds to complete. This happens with error : ESOCKETTIMEDOUT.
Is there a way to prevent this?
Here is my function:
function getTopCarsForUserWithPreferences(userId, genres) {
const pathToCars = admin.database().ref('cars');
pathTocars.orderByChild("IsTop").equalTo(true).once("value").then(function(snapshot) {
return writeSuggestedCars(userId, genres, snapshot);
}).catch(reason => {
console.log(reason)
})
}
function writeSuggestedCars(userId, genres, snapshot) {
const carsToWrite = {};
var snapCount = 0
snapshot.forEach(function(carSnapshot) {
snapCount += 1
const carDict = carSnapshot.val();
const carGenres = carDict.taCarGenre;
const genre_one = genres[0];
const genre_two = genres[1];
if (carGenres[genre_one] === true ||carGenres[genre_two] == true) {
carsToWrite[carSnapshot.key] = carDict
}
if (snapshot.numChildren() - 1 == snapCount) {
const pathToSuggest = admin.database().ref('carsSuggested').child(userId);
pathToSuggest.set(carsToWrite).then(snap => {
}).catch(reason => {
console.log(reason)
});
}
});
}
The getTopCarsForUserWithPreferences gets called when a user adds preferences. Also the cars table has about 50k entries.
Well you need to return everytime you use a async task.
Edit: you return 'writeSuggestedCars' but I think it never returns a value. I do not have a compiler, but I thought it was return Promise.resolved(). Can you insert it where I putted 'HERE'?
Maybe this will work:
function getTopCarsForUserWithPreferences(userId, genres) {
const pathToCars = admin.database().ref('cars');
return pathTocars.orderByChild("IsTop").equalTo(true).once("value").then(function(snapshot) {
return writeSuggestedCars(userId, genres, snapshot);
}).catch(reason => {
console.log(reason)
})
}
function writeSuggestedCars(userId, genres, snapshot) {
const carsToWrite = {};
var snapCount = 0
snapshot.forEach(function(carSnapshot) {
snapCount += 1
const carDict = carSnapshot.val();
const carGenres = carDict.taCarGenre;
const genre_one = genres[0];
const genre_two = genres[1];
if (carGenres[genre_one] === true ||carGenres[genre_two] == true) {
carsToWrite[carSnapshot.key] = carDict
}
if (snapshot.numChildren() - 1 == snapCount) {
const pathToSuggest = admin.database().ref('carsSuggested').child(userId);
return pathToSuggest.set(carsToWrite).then(snap => {
// 'HERE' I think return promise/Promise.resolve() will work
}).catch(reason => {
console.log(reason)
});
}
});
}

Resources