0

I am trying to insert an entry in cosmosDB container and getting TypeError: Converting circular structure to JSON error intermittently. I am not sure what is the root cause here.

Furthermore, I have tried some other Stack Overflow suggestions like following, but no luck:

Error:

error - TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Timeout'
    |     property '_idlePrev' -> object with constructor 'TimersList'
    --- property '_idleNext' closes the circle
partnersusers   error (2022-07-11T16:10:39.402-04:00) error in create(): TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Timeout'
    |     property '_idlePrev' -> object with constructor 'TimersList'
    --- property '_idleNext' closes the circle - UsersRepository
partnersusers   error (2022-07-11T16:10:39.403-04:00) error while creating user - UsersService
partnersusers   error (2022-07-11T16:10:39.403-04:00) Error during user creation - TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Timeout'
    |     property '_idlePrev' -> object with constructor 'TimersList'
    --- property '_idleNext' closes the circle - UsersController
partnersusers   error (2022-07-11T16:10:39.419-04:00) Converting circular structure to JSON
    --> starting at object with constructor 'Timeout'
    |     property '_idlePrev' -> object with constructor 'TimersList'
    --- property '_idleNext' closes the circle

Code:

users.controller.ts:

  @Post()
  async create(@Body() createUserDto: CreateUserDto): Promise<User> {
    try {
      const token: Token = await this.getToken();
      const authUser = await this.authService.createAuthUser(
        createUserDto,
        token,
      );

      const response: User = await this.usersService.create(
        createUserDto,
        authUser,
      );

      const transformedUser: User = await this.transformUser(response);
      this.logService.log(
        `user created successfully - ${this.constructor.name}`,
        transformedUser,
        'create',
      );

      return transformedUser;
    } catch (error) {
      this.logService.error(
        `Error during user creation - ${error} - ${this.constructor.name}`,
        error,
        'create',
      );
      throw error;
    }
  }

users.service.ts:

  async create(
    createUserDto: CreateUserDto,
    authUser: CreateUser,
  ): Promise<User> {
    try {
      const user: User = {
        id: authUser.user_id,
        contact: {
          firstName: createUserDto.contact.firstName,
          lastName: createUserDto.contact.lastName,
          email: createUserDto.contact.email,
          phoneNumber: createUserDto.contact.phoneNumber,
        },
        isReceiveText: createUserDto.isReceiveText,
        isSamePrimaryContactInfo: createUserDto.isReceiveText,
        primaryContact: {
          firstName: createUserDto.primaryContact.firstName,
          lastName: createUserDto.primaryContact.lastName,
          email: createUserDto.primaryContact.email,
          phoneNumber: createUserDto.primaryContact.phoneNumber,
        },
        businesses: createUserDto.businesses,
        audit: {
          createdOn: new Date(),
        },
        isActive: true,
      };
      const response = await this.userRepository.create(user);
      this.logService.log(
        `User created successfully - ${this.constructor.name}`,
        response,
        'create',
      );
      return response;
    } catch (error) {
      this.logService.error(
        `error while creating user - ${this.constructor.name}`,
        error,
        'create',
      );
      throw error;
    }
  }

users.repository.ts:

  async create(item: User): Promise<User> {
    let response: User | ItemResponse<User> | PromiseLike<User>;
    // let response;
    try {
      console.log(`222 - ${JSON.stringify(item)}`);
      response = await this.container.items.create(item);
      // response = await this.container.items.upsert(item);
      this.logService.log(
        `User record created successfully - ${this.constructor.name}`,
        response,
        'create',
      );
      return response.resource;
    } catch (error) {
      console.log(`error - ${error}`);
      if (error.code !== 409) {
        this.logService.error(
          `error in create(): ${error} - ${this.constructor.name}`,
          error,
          'create',
        );
        throw error;
      }
      response = await this.findById(item.id);
      return response;
    }
  }

Request: (This is console.log("222 - ${JSON.stringify(item)}"); from .repository.ts file. I see same entry in container as well even after the error.

{
  "id": "someID",
  "contact": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe3@gmail.com",
    "phoneNumber": "123-456-7890"
  },
  "isReceiveText": false,
  "isSamePrimaryContactInfo": false,
  "primaryContact": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@gmail.com",
    "phoneNumber": "123-456-7890"
  },
  "businesses": [
    {
      "role": {
        "type": "General Manager",
        "services": [
          { "type": "Buy Inventory" },
          { "type": "Sell Inventory" }
        ]
      }
    }
  ],
  "audit": { "createdOn": "2022-07-11T20:01:14.768Z" },
  "isActive": true
}
GThree
  • 2,708
  • 7
  • 34
  • 67

1 Answers1

0

I found out that, I was returning an entire cosmos object in return and trying to log that, which was throwing an error. That was the reason the record was saved but still getting the error. Meaning, I was looking at the wrong place.

In repository, instead of logging response object, I needed to log response.resource.

Fix: (users.repository.ts)

async create(item: User): Promise<User> {
    let response: User | ItemResponse<User> | PromiseLike<User>;
    // let response;
    try {
      console.log(`222 - ${JSON.stringify(item)}`);
      response = await this.container.items.create(item);
      // response = await this.container.items.upsert(item);
      this.logService.log(
        `User record created successfully - ${this.constructor.name}`,
        response.resource, <----- FIX
        'create',
      );
      return response.resource;
    } catch (error) {
      console.log(`error - ${error}`);
      if (error.code !== 409) {
        this.logService.error(
          `error in create(): ${error} - ${this.constructor.name}`,
          error,
          'create',
        );
        throw error;
      }
      response = await this.findById(item.id);
      return response;
    }
  }
GThree
  • 2,708
  • 7
  • 34
  • 67