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

process.hrtime.bigint() comes back as undefined #43920

Closed
sshevlyagin opened this issue Jul 20, 2022 · 8 comments
Closed

process.hrtime.bigint() comes back as undefined #43920

sshevlyagin opened this issue Jul 20, 2022 · 8 comments
Labels
process Issues and PRs related to the process subsystem.

Comments

@sshevlyagin
Copy link

sshevlyagin commented Jul 20, 2022

Version

16.15.1

Platform

Linux XXX 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

I have a nestjs app that gets tested using jest. Sometimes when the tests are being run on our build machine process.hrtime.bigint() comes back as undefined. I have not been able to repro this locally.

How often does it reproduce? Is there a required condition?

Randomly on build machine.

What is the expected behavior?

It's never undefined.

What do you see instead?

undefined

export function getHrTimeBigInt(): bigint {
  const hrTimeBigInt = process.hrtime.bigint();
  if (hrTimeBigInt === undefined) {
    getLogger().error(`Hell has frozen over bigint is undefined`);
    return BigInt(0);
  }
  return hrTimeBigInt;
}

Only when tests are run on our build machine

console.error
      [winston] Attempt to write logs with no transports {"message":"Hell has frozen over bigint is undefined","level":"error"}

Additional information

No response

@daeyeon daeyeon added the process Issues and PRs related to the process subsystem. label Jul 21, 2022
@mscdex
Copy link
Contributor

mscdex commented Jul 21, 2022

I don't see how it could possibly return undefined. Perhaps some third party module is overriding that function's implementation?

@sshevlyagin
Copy link
Author

I’m with you. The code runs in 30 tests and ends up failing like that in one or two of them consistently.

Does not fail on my M1 Mac so no local repro.

@mscdex
Copy link
Contributor

mscdex commented Jul 21, 2022

Perhaps when it returns undefined, try doing console.log(process.hrtime.bigint.toString()); to see if it at least matches what's in node core.

@targos
Copy link
Member

targos commented Jul 21, 2022

You can also try to freeze process and process.hrtime before running the tests. It should throw an error and show what is trying to override it.

@aduh95
Copy link
Contributor

aduh95 commented Jul 21, 2022

You can also try to freeze process and process.hrtime before running the tests. It should throw an error and show what is trying to override it.

Only if your code is in strict mode ("use strict" in CJS file, or an ESM file); in sloppy mode it will silently ignore the override (which should make your test pass but won't tell you what is trying to override that method).

@sshevlyagin
Copy link
Author

I'm using typescript so it's set to strict, I tried logging out process.hrtime and process.hrtime.bigint and it seems fine...

bigint: function () {\n        return fn.apply(this, arguments);\n      } 
hrtime: function hrtime(time) {\n  binding.hrtime();\n\n  if (time !== undefined) {\n    validateArray(time, 'time');\n    if (time.length !== 2) {\n      throw new ERR_OUT_OF_RANGE('time', 2, time.length);\n    }\n\n    const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0];\n    const nsec = hrValues[2] - time[1];\n    const needsBorrow = nsec < 0;\n    return [needsBorrow ? sec - 1 : sec, needsBorrow ? nsec + 1e9 : nsec];\n  }\n\n  return [\n    hrValues[0] * 0x100000000 + hrValues[1],\n    hrValues[2],\n  ];\n}"

The code

export function getHrTimeBigInt(): bigint {
 const hrTimeBigInt = process.hrtime.bigint();
 if (hrTimeBigInt === undefined) {
   getLogger().error(
     `Hell has frozen over bigint is undefined. bigint: ${process.hrtime.bigint.toString()} hrtime: ${process.hrtime.toString()}`,
   );
   return BigInt(0);
 }
 return hrTimeBigInt;
}

@mscdex
Copy link
Contributor

mscdex commented Jul 21, 2022

Looks like bigint is being overwritten by some module (perhaps webpack or similar is forcing the use of some polyfill or is assuming it doesn't exist so it doesn't check that it exists first).

This:

function () {
    return fn.apply(this, arguments);
} 

should look more like this:

function hrtimeBigInt() {
  binding.hrtimeBigInt();
  return hrBigintValues[0];
}

@sshevlyagin
Copy link
Author

Alright gang, I found the issue. Turns out replacing process.hrtime and putting it back in a separate test file was breaking things for reasons I don't quite understand. Thank you for humoring my OMG NODE IS BROKEN IN WAYS IT CAN'T BE thread.

it('didResolveOperation should record start time', async () => {
    const hrtime = process.hrtime;
    process.hrtime.bigint = jest.fn().mockReturnValueOnce(BigInt(100000000));

    expect(listeners.didResolveOperation).toBeDefined();
    if (!listeners.didResolveOperation) {
      throw new Error('didResolveOperation undefined');
    }
    const context = {} as GraphQLRequestContextDidResolveOperationCustomized<GqlContext>;
    await listeners.didResolveOperation(context);
    expect(context.startTime).toEqual(BigInt(100000000));
    process.hrtime = hrtime;
  });

@sshevlyagin sshevlyagin closed this as not planned Won't fix, can't repro, duplicate, stale Jul 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
process Issues and PRs related to the process subsystem.
Projects
None yet
Development

No branches or pull requests

5 participants