From a5a0ac2e0a4dc6b5ab7840809e70d08dc177d01f Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Thu, 23 Feb 2023 09:53:09 +0200 Subject: [PATCH] Clone errors before masking and make fields writable, fix #217 --- examples/nodejs/index2.ts | 15 +++++++++++++++ src/BaseLogger.ts | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/examples/nodejs/index2.ts b/examples/nodejs/index2.ts index a691527..5aed5e5 100644 --- a/examples/nodejs/index2.ts +++ b/examples/nodejs/index2.ts @@ -94,3 +94,18 @@ const log = new Logger({ log.info(error); //////////////////////////// + +function createReadonlyError(message: string, property: string) { + const error = new Error(message); + Object.defineProperty(error, "property", { + value: property, + writable: false, + enumerable: true, + configurable: false, + }); + return error; +} + +const e = createReadonlyError("message", "property"); + +logger.error(e); diff --git a/src/BaseLogger.ts b/src/BaseLogger.ts index 58f2a4b..cc44fb2 100644 --- a/src/BaseLogger.ts +++ b/src/BaseLogger.ts @@ -217,7 +217,7 @@ export class BaseLogger { ? this.settings.maskPlaceholder : this._recursiveCloneAndMaskValuesOfKeys((source as { [key: string]: unknown })[prop], keys, seen); return o; - }, source) + }, this._cloneError(source as Error)) : source != null && typeof source === "object" ? Object.getOwnPropertyNames(source).reduce((o, prop) => { // mask @@ -275,6 +275,21 @@ export class BaseLogger { return clonedLogObj; } + private _cloneError(error: T): T { + const ErrorConstructor = error.constructor as new (message?: string) => T; + const newError = new ErrorConstructor(error.message); + Object.assign(newError, error); + const propertyNames = Object.getOwnPropertyNames(newError); + for (const propName of propertyNames) { + const propDesc = Object.getOwnPropertyDescriptor(newError, propName); + if (propDesc) { + propDesc.writable = true; + Object.defineProperty(newError, propName, propDesc); + } + } + return newError; + } + private _toErrorObject(error: Error): IErrorObject { return { nativeError: error,