UNPKG

@stacksjs/error-handling

Version:
7 lines 3.61 kB
import fs from"node:fs";import{dirname}from"node:path";import*as process from"node:process";function italic(str){return`\x1B[3m${str}\x1B[23m`}function stripAnsi(str){return str.replace(/\x1B\[[0-9;]*m/g,"")}import*as path from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";export class ErrorHandler{static isTestEnvironment=!1;static shouldExitProcess=!1;static handle(err,options){if(!this.isTestEnvironment)this.shouldExitProcess=options?.shouldExit===!0;if(options?.silent!==!0)this.writeErrorToConsole(err);let errorMessage;if(options?.message)errorMessage=options.message;else if(err instanceof Error)errorMessage=err.message;else if(typeof err==="string")errorMessage=err;else errorMessage=JSON.stringify(err);const error=Error(errorMessage);if(err instanceof Error)Object.assign(error,err);this.writeErrorToFile(error).catch((e)=>console.error(e));return error}static handleError(err,options){this.handle(err,options);return err}static async writeErrorToFile(err,context){if(!(err instanceof Error)){console.error("Error is not an instance of Error:",err);return}const contextStr=context?` | url=${context.url||"N/A"} method=${context.method||"N/A"} user=${context.userId||"anonymous"}`:"",stackLine=err.stack?` ${err.stack.split(` `).slice(1,4).join(` `)}`:"",formattedError=`[${new Date().toISOString()}] ${err.name}: ${err.message}${contextStr}${stackLine} `,logFilePath=path.logsPath("stacks.log")??path.logsPath("errors.log");try{await fs.promises.mkdir(path.dirname(logFilePath),{recursive:!0});await fs.promises.appendFile(logFilePath,formattedError)}catch(error){console.error("Failed to write to error file:",error)}}static writeErrorToConsole(err){let errorString;if(err instanceof Error)errorString=err.message;else if(typeof err==="string")errorString=err;else errorString=JSON.stringify(err);console.error(errorString);if(errorString.includes("bunx --bun cdk destroy")||errorString===`Failed to execute command: ${italic("bunx --bun eslint . --fix")}`||errorString===`Failed to execute command: ${italic("bun storage/framework/core/actions/src/lint/fix.ts")}`){if(!this.isTestEnvironment){console.log("No need to worry. The edge function is currently being destroyed. Please run `buddy undeploy` shortly again, and continue doing so until it succeeds running.");console.log("Hoping to see you back soon!")}}if(this.shouldExitProcess)process.exit(ExitCode.FatalError)}}let defaultLogPath="storage/logs/stacks.log";export function setLogPath(path){defaultLogPath=path}export async function writeToLogFile(message,options){const formattedMessage=`[${new Date().toISOString()}] ${message} `,logFile=options?.logFile??defaultLogPath,dirPath=dirname(logFile);await fs.promises.mkdir(dirPath,{recursive:!0});await fs.promises.appendFile(logFile,formattedMessage)}export function handleError(err,options){let errorMessage,contextData,errorOptions;if(options&&typeof options==="object"&&(("shouldExit"in options)||("silent"in options)))errorOptions=options;else if(options!==void 0)contextData=options&&typeof options==="object"?options:{error:options};const errMsg=err instanceof Error?err.message:typeof err==="string"?err:JSON.stringify(err);if(errorOptions?.message)errorMessage=`${errMsg}: ${errorOptions.message}`;else errorMessage=errMsg;let logMessage=`ERROR: ${stripAnsi(errorMessage)}`;if(contextData)logMessage+=` Context: ${JSON.stringify(contextData,null,2)}`;writeToLogFile(logMessage).catch((err)=>{console.error("Failed to write error log:",err)});const error=Error(errorMessage);if(err instanceof Error)Object.assign(error,err);return ErrorHandler.handle(error,errorOptions)}