Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: When calling tracer.wrap on a method that accepts a class constructor function as its last arguments causes unexpected behaviour #5085

Open
jcelmeta14 opened this issue Jan 8, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@jcelmeta14
Copy link

jcelmeta14 commented Jan 8, 2025

Tracer Version(s)

5.22.0

Node.js Version(s)

20.18.1

Bug Report

Apologies in advance, I do not have much experience in opening issues!

I have a case when I am wrapping a method with tracer.wrap and this methods takes a class constructor function as its last argument. This is triggering the if condition on line 125 of tracer.js in dd-trace which overrides the last argument. Later on this class constructor is being used create an instance and do something with it. As it stands, I get the following error:

TypeError: Class constructor MyClassConstructorArgument cannot be invoked without 'new'

Reproduction Code

A trace decorator, used to wrap class methods I want to trace

export function Trace(target: unknown, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor {
  const originalMethod = descriptor.value;
  descriptor.value = tracer.wrap(originalMethod.name, originalMethod);
  return descriptor;
}

A class with a method I want to trace, whose last argument is a class constructor

import { DecorateAll } from 'decorate-all';
import { ClassConstructor, plainToInstance } from 'class-transformer';

@DecorateAll(Trace, { deep: true })
export class SomeService {

public async someMethodToTrace(
    someParam: SomeOtherType,
    validatorClass: ClassConstructor<DtoClassWithValidationAsDecorators>
  ): Promise<SomeReturnType> {
  console.log(validatorClass.prototype) // logs {}
  // somewhere in the code this is called, which probably internally calls new validatorClass(...)
  // plainToInstance(validatorClass, someObjectPlainObject)
}

This dto class extends a base class

class DtoClassWithValidationAsDecorators extends DtoBaseClass {
 // some properties with some decorators with overriden validation logic from the base class
}

Somewhere the method is called:

console.log(DtoClassWithValidationAsDecorators.prototype) // logs DtoBaseClass
someServiceInstance.someMethodToTrace(someParam, DtoClassWithValidationAsDecorators);

So before the traced method is called, logging the prototype results in DtoBaseClass
But inside the traced method, because of what happens inside tracer.js line 125, logging results in {}

Error Logs

TypeError: Class constructor DtoClassWithValidationAsDecorators cannot be invoked without 'new'

Honestly, I do not know what to put in here. My situation is also a little bit weird as well. In principle I have some code that is upserting something, and I want to apply different validation logics in different scenarios, hence the class constructor function as a parameter. I have to say that the validation should happen separately and not inside the same function that is being traced (it is doing way too many things), but I am stuck with it for now and I cannot change it.

Tracer Config

No response

Operating System

No response

Bundling

Webpack

@jcelmeta14 jcelmeta14 added the bug Something isn't working label Jan 8, 2025
@jcelmeta14 jcelmeta14 changed the title [BUG]: When calling tracer.wrap on a method that accepts a class constructor function as its last arguments causes weird behaviour [BUG]: When calling tracer.wrap on a method that accepts a class constructor function as its last arguments causes unexpected behaviour Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant