alphamikle / nest_transact

Simplest transactions support for Nestjs with Typeorm
MIT License
116 stars 20 forks source link

Services get pulled in as Entity element in transaction #24

Open SocDean opened 1 year ago

SocDean commented 1 year ago

Description

Please see the code below, I've tried to debug this problem, but I was unsuccessful. Any help is much appreciated

Error stacktrace:

UnknownElementException [Error]: Nest could not find UsersService element (this provider does not exist in the current context)
    at InstanceLinksHost.get (/Users/repos/api/node_modules/@nestjs/core/injector/instance-links-host.js:15:19)
    at Object.find (/Users/repos/api/node_modules/@nestjs/core/injector/module-ref.js:39:55)
    at Object.get (/Users/repos/api/node_modules/@nestjs/core/injector/module.js:350:28)
    at UsersService.getArgument (/Users/repos/api/node_modules/nest-transact/dist/lib/with-transaction.js:31:35)
    at /Users/repos/api/node_modules/nest-transact/dist/lib/with-transaction.js:83:43
    at Array.forEach (<anonymous>)
    at UsersService.findArgumentsForProvider (/Users/repos/api/node_modules/nest-transact/dist/lib/with-transaction.js:79:14)
    at UsersService.getArgument (/Users/repos/api/node_modules/nest-transact/dist/lib/with-transaction.js:71:29)
    at /Users/repos/api/node_modules/nest-transact/dist/lib/with-transaction.js:83:43
    at Array.forEach (<anonymous>) 

Controller code

@ApiTags('Users')
@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService, private readonly dataSource: DataSource) {}

  @Post('create-user')
  @ApiOperation({
    summary: 'Role: open. Creates: User, User.stripe, User.inventory for all itemTypes, User.address',
    description: 'Creates user. For address please enter both types of address: bill_to and ship_to.',
  })
  @ApiBody({ type: CreateUserDto, required: true })
  @ApiResponse({ type: Boolean, status: 201 })
  async create(@Body() createUserDto: CreateUserDto): Promise<boolean> {
    return await this.dataSource.transaction(manager => this.usersService.withTransaction(manager).create({ createUserDto }));
  }
} 

Service code:

@Injectable()
export class UsersService extends TransactionFor<UsersService> {
  private readonly logger = new Logger(UsersService.name);

  constructor(
    private readonly eventEmitter: EventEmitter2,
    private readonly paymentService: PaymentService,
    private readonly eventStore: EventStore,
    private readonly inventoryService: InventoryService,
    private readonly encryptionService: EncryptionService,
    private readonly itemService: ItemService,
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
    moduleRef: ModuleRef,
  ) {
    super(moduleRef);
    this.registerAdmin();
  }

  async create({ createUserDto }: { createUserDto: CreateUserDto }): Promise<boolean> {
    let stripeId: string;
    try {
      const newUser = new UserEntity();
      for (const key in createUserDto) {
        newUser[key] = createUserDto[key];
      }
      newUser.password = await this.encryptionService.encrypt({ password: createUserDto.password });
      newUser.stripe = await this.paymentService.createStripeAccount({ newUser });
      stripeId = newUser.stripe.id;
      newUser.magicToken = [];
      newUser.magicToken.push(crypto.randomBytes(30).toString('hex'));

      const inventories = await this.inventoryService.addInventoryToEntity({ user: newUser });
      newUser.inventories = [];
      for (const inventory of inventories) {
        newUser.inventories.push(inventory);
      }

      await this.userRepository.save(newUser);
      this.logger.log(`New User ${newUser.id} created.`);
      this.eventEmitter.emit(Events.UserRegistered, new UserRegisteredEvent(newUser.email, newUser.magicToken[0]));
      await this.eventStore.appendEvent(newUser, new CreateUserEvent({ id: newUser.id }, createUserDto));
      return true;
    } catch (err) {
      this.logger.error(err);
      await this.paymentService.deleteStripeAccount({ stripeId });
      throw err;
    }
  }
}
alphamikle commented 1 year ago

Hi @SocDean ! Is this problem still present? And is it really related to the nest-transact? What would you see if you will remove ... extends TransactionFor<UsersService>?