mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
199 lines
4.7 KiB
TypeScript
199 lines
4.7 KiB
TypeScript
import { db } from "./firebaseConfig";
|
|
import admin from "firebase-admin";
|
|
|
|
function firetableUser(user: admin.auth.UserRecord) {
|
|
return {
|
|
displayName: user?.displayName,
|
|
email: user?.email,
|
|
uid: user?.uid,
|
|
emailVerified: user?.emailVerified,
|
|
photoURL: user?.photoURL,
|
|
timestamp: new Date(),
|
|
};
|
|
}
|
|
|
|
async function insertErrorRecordToDB(errorRecord: object) {
|
|
await db.collection("_FT_ERRORS").add(errorRecord);
|
|
}
|
|
|
|
async function insertErrorToStreamer(errorRecord: object, streamLogger) {
|
|
let errorString = "";
|
|
for (const key of [
|
|
"command",
|
|
"description",
|
|
"functionConfigTs",
|
|
"extensionsConfig",
|
|
"stderr",
|
|
"errorStackTrace",
|
|
]) {
|
|
const value = errorRecord[key];
|
|
if (value) {
|
|
errorString += `\n\n${key}: ${value}`;
|
|
}
|
|
}
|
|
await streamLogger.error(errorString);
|
|
}
|
|
|
|
function commandErrorHandler(
|
|
meta: {
|
|
user: admin.auth.UserRecord;
|
|
description?: string;
|
|
functionConfigTs?: string;
|
|
extensionsConfig?: string;
|
|
},
|
|
streamLogger
|
|
) {
|
|
return async function (error, stdout, stderr) {
|
|
await streamLogger.info(stdout);
|
|
|
|
if (!error) {
|
|
return;
|
|
}
|
|
|
|
const errorRecord = {
|
|
errorType: "commandError",
|
|
ranBy: firetableUser(meta.user),
|
|
createdAt: admin.firestore.FieldValue.serverTimestamp(),
|
|
stdout: stdout ?? "",
|
|
stderr: stderr ?? "",
|
|
errorStackTrace: error?.stack ?? "",
|
|
command: error?.cmd ?? "",
|
|
description: meta?.description ?? "",
|
|
functionConfigTs: meta?.functionConfigTs ?? "",
|
|
extensionsConfig: meta?.extensionsConfig ?? "",
|
|
};
|
|
await insertErrorToStreamer(errorRecord, streamLogger);
|
|
insertErrorRecordToDB(errorRecord);
|
|
};
|
|
}
|
|
|
|
async function logErrorToDB(
|
|
data: {
|
|
errorDescription: string;
|
|
errorExtraInfo?: string;
|
|
errorTraceStack?: string;
|
|
user: admin.auth.UserRecord;
|
|
extensionsConfig?: string;
|
|
},
|
|
streamLogger?
|
|
) {
|
|
console.error(data.errorDescription);
|
|
|
|
const errorRecord = {
|
|
errorType: "codeError",
|
|
ranBy: firetableUser(data.user),
|
|
description: data.errorDescription,
|
|
createdAt: admin.firestore.FieldValue.serverTimestamp(),
|
|
extensionsConfig: data?.extensionsConfig ?? "",
|
|
errorExtraInfo: data?.errorExtraInfo ?? "",
|
|
errorStackTrace: data?.errorTraceStack ?? "",
|
|
};
|
|
if (streamLogger) {
|
|
await insertErrorToStreamer(errorRecord, streamLogger);
|
|
}
|
|
insertErrorRecordToDB(errorRecord);
|
|
}
|
|
|
|
function parseExtensionsConfig(
|
|
extensions: string | undefined,
|
|
user: admin.auth.UserRecord,
|
|
streamLogger
|
|
) {
|
|
if (extensions) {
|
|
try {
|
|
// remove leading "extensions.config(" and trailing ")"
|
|
return extensions
|
|
.replace(/^(\s*)extensions.config\(/, "")
|
|
.replace(/\);?\s*$/, "");
|
|
} catch (error) {
|
|
logErrorToDB(
|
|
{
|
|
errorDescription: "Extensions is not wrapped with extensions.config",
|
|
errorTraceStack: error.stack,
|
|
user,
|
|
extensionsConfig: extensions,
|
|
},
|
|
streamLogger
|
|
);
|
|
}
|
|
}
|
|
|
|
return "[]";
|
|
}
|
|
|
|
async function createStreamLogger(tableConfigPath: string) {
|
|
const startTimeStamp = Date.now();
|
|
const fullLog: {
|
|
log: string;
|
|
level: "info" | "error";
|
|
timestamp: number;
|
|
}[] = [];
|
|
const logRef = db
|
|
.doc(tableConfigPath)
|
|
.collection("ftBuildLogs")
|
|
.doc(startTimeStamp.toString());
|
|
await logRef.set({ startTimeStamp, status: "BUILDING" });
|
|
|
|
console.log(
|
|
`streamLogger created. tableConfigPath: ${tableConfigPath}, startTimeStamp: ${startTimeStamp}`
|
|
);
|
|
|
|
return {
|
|
info: async (log: string) => {
|
|
console.log(log);
|
|
fullLog.push({
|
|
log,
|
|
level: "info",
|
|
timestamp: Date.now(),
|
|
});
|
|
await logRef.update({
|
|
fullLog,
|
|
});
|
|
},
|
|
error: async (log: string) => {
|
|
console.error(log);
|
|
fullLog.push({
|
|
log,
|
|
level: "error",
|
|
timestamp: Date.now(),
|
|
});
|
|
await logRef.update({
|
|
fullLog,
|
|
});
|
|
},
|
|
end: async () => {
|
|
const logsDoc = await logRef.get();
|
|
const errorLog = logsDoc
|
|
.get("fullLog")
|
|
.filter((log) => log.level === "error");
|
|
if (errorLog.length !== 0) {
|
|
console.log("streamLogger marked as FAIL");
|
|
await logRef.update({
|
|
status: "FAIL",
|
|
failTimeStamp: Date.now(),
|
|
});
|
|
} else {
|
|
console.log("streamLogger marked as SUCCESS");
|
|
await logRef.update({
|
|
status: "SUCCESS",
|
|
successTimeStamp: Date.now(),
|
|
});
|
|
}
|
|
},
|
|
fail: async () => {
|
|
console.log("streamLogger marked as FAIL");
|
|
await logRef.update({
|
|
status: "FAIL",
|
|
failTimeStamp: Date.now(),
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
export {
|
|
commandErrorHandler,
|
|
logErrorToDB,
|
|
parseExtensionsConfig,
|
|
createStreamLogger,
|
|
};
|