UNPKG

@embeddable.com/sdk-core

Version:

Core Embeddable SDK module responsible for web-components bundling and publishing.

113 lines (99 loc) 2.89 kB
import * as fs from "node:fs/promises"; import * as path from "node:path"; import { getSDKVersions } from "./utils"; const LOG_DIR = path.join(process.cwd(), ".embeddable", "logs"); export const ERROR_LOG_FILE = path.join(LOG_DIR, "error.log"); const MAX_LOG_SIZE = 5 * 1024 * 1024; // 5 MB const MAX_LOG_FILES = 5; interface LogEntry { timestamp: string; command: string; breadcrumbs: string[]; error: string; } interface LogErrorParams { command: string; breadcrumbs: string[]; error: unknown; } export async function initLogger(command: string) { try { await fs.mkdir(LOG_DIR, { recursive: true }); } catch (error) { console.error("Failed to create log directory:", error); } setupGlobalErrorHandlers(command); } export async function logError({ command, breadcrumbs, error, }: LogErrorParams) { const sdkVersions = getSDKVersions(); const logEntry: LogEntry = { timestamp: new Date().toISOString(), command, breadcrumbs, error: error instanceof Error ? `${error.name}: ${error.message}\n${error.stack}` : String(error), }; const logMessage = ` [${logEntry.timestamp}] Command: ${logEntry.command} Breadcrumbs: ${logEntry.breadcrumbs.join(" > ")} Error: ${logEntry.error} OS: ${process.platform} Node: ${process.version} SDK Versions: ${JSON.stringify(sdkVersions, null, 2)} ---------------------------------------- `; try { await rotateLogIfNeeded(); await fs.appendFile(ERROR_LOG_FILE, logMessage); console.error( `An error occurred during ${command}. Check the log file for details: ${ERROR_LOG_FILE}`, ); } catch (error) { console.error("Failed to write to log file:", error); } } async function rotateLogIfNeeded() { try { const stats = await fs.stat(ERROR_LOG_FILE); if (stats.size < MAX_LOG_SIZE) { return; } for (let i = MAX_LOG_FILES - 1; i > 0; i--) { const oldFile = `${ERROR_LOG_FILE}.${i}`; const newFile = `${ERROR_LOG_FILE}.${i + 1}`; try { await fs.rename(oldFile, newFile); } catch (error) { // Ignore error if file doesn't exist } } await fs.rename(ERROR_LOG_FILE, `${ERROR_LOG_FILE}.1`); await fs.writeFile(ERROR_LOG_FILE, ""); // Create a new empty log file } catch (error: any) { if (error.code !== "ENOENT") { console.error("Error rotating log file:", error); } } } function setupGlobalErrorHandlers(command: string) { process.on("uncaughtException", async (error) => { await logError({ command, breadcrumbs: ["uncaughtException"], error }); console.error(error); process.exit(1); }); process.on("unhandledRejection", async (reason) => { await logError({ command, breadcrumbs: ["unhandledRejection"], error: reason as Error | string, }); console.error(reason); process.exit(1); }); }