import inspect from "object-inspect";
import { logInfo, logError } from "#lib/UtilsLog";
/**
* Utility functions for debugging
* @module Debug
*/
/**
* 为函数添加调试日志包装,自动记录函数调用前后的参数和返回值
* @template {Function} T - 需要被包装的目标函数类型
* @param {T} func - 需要被包装的目标函数
* @returns {T} 包装后的函数,调用时会先打印入参日志,执行后打印返回值日志
*
* @example
* import { attachLogToFunc } from 'nsuite
* attachLogToFunc(console.log)("hello world")
*/
export function attachLogToFunc(func) {
/**
* 包装后的函数,调用时会先打印入参日志,执行后打印返回值日志
* @param {...*} args - 调用目标函数的参数
* @returns {*} 目标函数的返回值
*/
const wrapperFunc = (...args) => {
logInfo();
logInfo(`[DEBUG BEFORE] calling ${func.name} with args: ${inspect(args)}`);
const result = func(...args);
// 检查返回值是否为 Promise/thenable,若是则等待解析后再打印日志
if (typeof result?.then === "function") {
// 若返回值为 Promise,则等待解析后再打印日志
return result
.then(
/**
* 处理 Promise 解析后的结果,打印日志并透传结果
* @param {*} resolvedResult - Promise 成功解析后的返回值
* @returns {*} 透传解析结果以维持 Promise 链式调用
*/
(resolvedResult) => {
logInfo();
logInfo(
`[DEBUG AFTER] called ${func.name} with args: ${inspect(args)} return: ${inspect(resolvedResult)}`,
);
logInfo();
return resolvedResult; // 保持原 Promise 链式调用能力
},
)
.catch(
/**
* 处理 Promise 拒绝错误,打印错误日志并透传错误
* @param {Error} error - Promise 被拒绝时的错误对象
* @throws {Error} 透传原始错误以维持 Promise 错误处理链
*/
(error) => {
logInfo();
logError(
`[DEBUG ERROR] called ${func.name} with args: ${inspect(args)} error: ${inspect(error)}`,
);
logInfo();
throw error; // 保持原 Promise 错误处理能力
},
);
}
// 非 Promise 结果直接打印日志
logInfo();
logInfo(
`[DEBUG AFTER] called ${func.name} with args: ${inspect(args)} return: ${inspect(result)}`,
);
logInfo();
return result;
};
// @ts-ignore
return /** @type {T} */ (/** @type {unknown} */ wrapperFunc);
}