From 7743ccbb04857f2e62eee71138225dadc1429d50 Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Mon, 7 Aug 2023 23:39:40 +0200 Subject: [PATCH] Support errors with multiple properties, Fix #227 --- examples/nodejs/index2.ts | 4 ++-- examples/nodejs/mongodb/package-lock.json | 8 ++++---- examples/nodejs/mongodb/package.json | 2 +- src/BaseLogger.ts | 23 +++++++---------------- src/runtime/browser/index.ts | 9 ++++++++- src/runtime/nodejs/index.ts | 10 +++++++++- tests/Nodejs/5_pretty_Log_Types.test.ts | 21 +++++++++++++++++++++ 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/examples/nodejs/index2.ts b/examples/nodejs/index2.ts index 9b8df31..d7f327e 100644 --- a/examples/nodejs/index2.ts +++ b/examples/nodejs/index2.ts @@ -1,5 +1,5 @@ import { Logger, BaseLogger } from "../../src/index.js"; -import { NodeRuntime } from "../../src/index.js"; +import { Runtime } from "../../src/index.js"; const defaultLogObject: { name: string; @@ -23,7 +23,7 @@ logger.fatal("test1 %s test3", "test2"); console.log("###############"); -const baseLogger = new BaseLogger(NodeRuntime, {}, defaultLogObject); +const baseLogger = new BaseLogger(Runtime, {}, defaultLogObject); baseLogger.log(0, "test", "test base logger", { haha: true, password: "123456" }, ["SECRET"]); diff --git a/examples/nodejs/mongodb/package-lock.json b/examples/nodejs/mongodb/package-lock.json index 6267be1..bd65a0e 100644 --- a/examples/nodejs/mongodb/package-lock.json +++ b/examples/nodejs/mongodb/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "mongodb": "^4.4.0", - "tslog": "^4.8.2", + "tslog": "^4.8.7", "typescript": "^5.1.6" }, "devDependencies": { @@ -1496,9 +1496,9 @@ "optional": true }, "node_modules/tslog": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.8.2.tgz", - "integrity": "sha512-eAKIRjxfSKYLs06r1wT7oou6Uv9VN6NW9g0JPidBlqQwPBBl5+84dm7r8zSOPVq1kyfEw1P6B3/FLSpZCorAgA==", + "version": "4.8.7", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.8.7.tgz", + "integrity": "sha512-8PhRxGQy1Q3SJ6ObGYKJR2j+AKqNGl3JMiGke6Y/u/gBXzBoWgAapEPCzTXKhsTmZgxoFbpcCAX9TAruPJFsMQ==", "engines": { "node": ">=16" }, diff --git a/examples/nodejs/mongodb/package.json b/examples/nodejs/mongodb/package.json index 6997b11..4668c24 100644 --- a/examples/nodejs/mongodb/package.json +++ b/examples/nodejs/mongodb/package.json @@ -6,7 +6,7 @@ "type": "module", "dependencies": { "mongodb": "^4.4.0", - "tslog": "^4.8.2", + "tslog": "^4.8.7", "typescript": "^5.1.6" }, "scripts": { diff --git a/src/BaseLogger.ts b/src/BaseLogger.ts index b673998..0591b7d 100644 --- a/src/BaseLogger.ts +++ b/src/BaseLogger.ts @@ -287,22 +287,13 @@ export class BaseLogger { } private _cloneError(error: T): T { - type ErrorProperties = keyof Error; - const ErrorConstructor = error.constructor as new (...args: unknown[]) => T; - const errorProperties = Object.getOwnPropertyNames(error) as ErrorProperties[]; - const errorArgs = errorProperties.map((propName) => error[propName]); - - const newError = new ErrorConstructor(...errorArgs); - Object.assign(newError, error); - - for (const propName of errorProperties) { - const propDesc = Object.getOwnPropertyDescriptor(newError, propName); - if (propDesc) { - propDesc.writable = true; - Object.defineProperty(newError, propName, propDesc); - } - } - return newError; + const cloned = new (error.constructor as { new (): T })(); + + Object.getOwnPropertyNames(error).forEach((key) => { + (cloned as any)[key] = (error as any)[key]; + }); + + return cloned; } private _toErrorObject(error: Error): IErrorObject { diff --git a/src/runtime/browser/index.ts b/src/runtime/browser/index.ts index ffeecd7..6db87dc 100644 --- a/src/runtime/browser/index.ts +++ b/src/runtime/browser/index.ts @@ -123,7 +123,14 @@ export function prettyFormatErrorObj(error: Error, settings: ISettings { + if (key !== "stack") { + result.push((error as any)[key]); + } + return result; + }, []) + .join(", "), errorStack: errorStackStr.join("\n"), }; return formatTemplate(settings, settings.prettyErrorTemplate, placeholderValuesError); diff --git a/src/runtime/nodejs/index.ts b/src/runtime/nodejs/index.ts index 1e113f4..e4dbac8 100644 --- a/src/runtime/nodejs/index.ts +++ b/src/runtime/nodejs/index.ts @@ -3,6 +3,7 @@ import { normalize as fileNormalize } from "path"; import { types, formatWithOptions, InspectOptions } from "util"; import { Runtime, ILogObjMeta, ISettings, IStackFrame } from "../../interfaces.js"; import { formatTemplate } from "../../formatTemplate.js"; +import { stdout } from "process"; export { InspectOptions }; export default { @@ -132,7 +133,14 @@ export function prettyFormatErrorObj(error: Error, settings: ISettings { + if (key !== "stack") { + result.push((error as any)[key]); + } + return result; + }, []) + .join(", "), errorStack: errorStackStr.join("\n"), }; return formatTemplate(settings, settings.prettyErrorTemplate, placeholderValuesError); diff --git a/tests/Nodejs/5_pretty_Log_Types.test.ts b/tests/Nodejs/5_pretty_Log_Types.test.ts index 3c3f65e..fd7564b 100644 --- a/tests/Nodejs/5_pretty_Log_Types.test.ts +++ b/tests/Nodejs/5_pretty_Log_Types.test.ts @@ -3,6 +3,13 @@ import { Logger } from "../../src"; import { getConsoleLog, mockConsoleLog } from "./helper.js"; import { stdout } from "process"; +class CustomError extends Error { + constructor(message: string, public extraInfo: string) { + super(message); + Object.setPrototypeOf(this, CustomError.prototype); + } +} + describe("Pretty: Log Types", () => { beforeEach(() => { mockConsoleLog(true, false); @@ -117,6 +124,20 @@ describe("Pretty: Log Types", () => { expect((errorLog?.stack as any)[0]?.fileName).toBe("5_pretty_Log_Types.test.ts"); }); + test("Error with multiple parameters", (): void => { + const logger = new Logger({ type: "pretty" }); + const errorLog = logger.log(1234, "testLevel", new CustomError("Something went wrong", "Additional info")); + expect(getConsoleLog()).toContain("Something went wrong"); + expect(getConsoleLog()).toContain("Additional info"); + expect(getConsoleLog()).toContain("Error"); + expect(getConsoleLog()).toContain("test"); + expect(getConsoleLog()).toContain("error stack:\n"); + expect(getConsoleLog()).toContain("5_pretty_Log_Types.test.ts"); + expect(getConsoleLog()).toContain("Object."); + expect(errorLog?.nativeError).toBeInstanceOf(Error); + expect((errorLog?.stack as any)[0]?.fileName).toBe("5_pretty_Log_Types.test.ts"); + }); + test("string and Error", (): void => { const logger = new Logger({ type: "pretty" }); const errorLog = logger.log(1234, "testLevel", "test", new Error("test"));