Ситуация следующая. У меня есть декоратор класса, которые устанавливает начальные значения настроек логирования. Есть пара методов, которые как раз и отвечают за то, как и что будет логироваться. Основная проблема в том, что при вызове функции originValue у меня теряются поля класса.
export function LoggerInit(options: ILoggerClass = defaultClassLoggerOptions) {
options = Object.assign({}, defaultClassLoggerOptions, options);
return function (target) {
target.prototype.logger = log;
target.prototype.__loggerOptions = options;
target.prototype.__className = options.name || target.name;
}
}
export function debug(options: ILoggerMethod = defaultMethodLoggerOptions) {
options = Object.assign({}, defaultMethodLoggerOptions, options);
return function (target: Object,
propertyKey: string | symbol,
descriptor: TypedPropertyDescriptor<any>) {
const originValue = descriptor.value;
descriptor.value = function (...args) {
return descriptorWrapper.call(this, "debug", originValue, options, propertyKey, args);
};
return descriptor;
}
}
async function descriptorWrapper(logMethod,
originValue,
options,
propertyKey,
args) {
let res;
let isPromise: boolean;
try {
res = await originValue.call(this, args);
isPromise = true;
}
catch (e) {
res = originValue.call(this, args);
isPromise = false;
}
const classOptions: ILoggerClass = this.__loggerOptions;
if (classOptions && classOptions.enabled && options.enabled) {
const className = this.__className;
const data = [`[${className}].${options.name || propertyKey}`];
if (options.withParams && !!args && !!args.length) {
data.push(`params: ${args.map(
a => JSON.stringify(a))
.join()}`);
}
if (options.withResult) {
data.push(`result ${JSON.stringify(res)}`);
}
log[logMethod](data.join(" | "));
}
return (isPromise) ? Promise.resolve(res) : res;
}
Примерный пример использования:
@LoggerInit({name: "Test"})
class MegaTest {
private logger: Logger;
private url = "localhost";
@debug()
getAll() {
this.logger.info("try to get all"); // тут ошибка
return Promise.resolve("test");
}
@debug()
getById(id: number) {
return service.get(this.url); // тут ошибка
}
}