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

Do not know how to serialize a BigInt #2375

Open
TomMettam opened this issue Jul 8, 2022 · 8 comments
Open

Do not know how to serialize a BigInt #2375

TomMettam opened this issue Jul 8, 2022 · 8 comments
Labels

Comments

@TomMettam
Copy link

TomMettam commented Jul 8, 2022

Type of Issue

[X] Bug Report
[ ] Feature Request

Description

When building an angular library, I get the error "Do not know how to serialize a BigInt"

My project does use BigInts, but doesn't attempt to serialize them at any point

------------------------------------------------------------------------------
Building entry point '@genius/frontend'
------------------------------------------------------------------------------
✔ Compiling with Angular sources in Ivy full compilation mode.
✖ Generating FESM2020
Do not know how to serialize a BigInt

How To Reproduce

It's unclear exactly what is being serialized here so I don't know how to reproduce the error

Expected Behaviour

Project should build

Version Information

$ node_modules/.bin/ng-packagr --version
ng-packagr:            14.0.3
@angular/compiler:     14.0.5
rollup:                2.75.7
typescript:            4.7.4

Please include all version numbers that might be relevant, e.g. third-party libraries

@alan-agius4
Copy link
Member

Hi @TomMettam,

I am unable to replicate. Can you please provide a minimal reproduction?

@TomMettam
Copy link
Author

I don't really know where to begin when doing that, because I can't imagine what it could be trying to serialise.

What does the app JSON encode during the process?

@alan-agius4
Copy link
Member

I suspected that it might be rollup, but without a reproduction it is hard to tell what is happened.

@TomMettam
Copy link
Author

TomMettam commented Jul 13, 2022

Hello.

Creating a minimal reproduction isn't feasible for me because my project is huge, and the error reported from ng-packagr isn't in any way helpful in knowing what might be triggering the errror. So I added some code to diagnose the issue.

The exception is thrown in rollup.js with the following line:

await (0, cache_1.saveCacheEntry)(cacheDirectory, opts.cacheKey, JSON.stringify(bundle.cache));

I added some code to scan the object for bigints, and it spat out the following:

bigint found at modules[3].ast.body[7].declaration.body.body[0].value.body.body[0].alternate.alternate.alternate.alternate.alternate.alternate.alternate.consequent.body[0].alternate.consequent.body[0].alternate.alternate.alternate.body[1].test.right.argument.value
bigint found at modules[3].ast.body[7].declaration.body.body[0].value.body.body[0].alternate.alternate.alternate.alternate.alternate.alternate.alternate.consequent.body[0].alternate.alternate.body[0].alternate.alternate.alternate.body[1].test.right.value
bigint found at modules[3].ast.body[7].declaration.body.body[0].value.body.body[0].alternate.alternate.alternate.alternate.alternate.alternate.alternate.alternate.consequent.body[0].consequent.body[0].test.right.argument.value
bigint found at modules[3].ast.body[7].declaration.body.body[0].value.body.body[0].alternate.alternate.alternate.alternate.alternate.alternate.alternate.alternate.consequent.body[0].alternate.test.right.value
bigint found at modules[4].ast.body[5].declaration.body.body[13].value.body.body[5].consequent.body[0].argument.left.value
bigint found at modules[4].ast.body[5].declaration.body.body[18].value.body.body[3].body.body[1].expression.right.right.value

I don't really know what any of these properties mean, but can you tell me, based on this, where the troublesome bigint may be sitting?

@alan-agius4
Copy link
Member

Thanks for the above, so it appears to be this line

await saveCacheEntry(cacheDirectory, opts.cacheKey, JSON.stringify(bundle.cache));
that is causing the problem.

@TomMettam
Copy link
Author

Well, I'm not sure if that is the "cause", it's the contents of bundle.cache which are the issue - there's a bigint in there which JSON.stringify can't serialize

@rehdie
Copy link

rehdie commented Jan 9, 2023

I've patched the script ng-packagr/src/lib/flatten/rollup.ts to find out, where the BigInt is located:

try {
	await (0, cache_1.saveCacheEntry)(cacheDirectory, opts.cacheKey, JSON.stringify(bundle.cache));
} catch(error) {
	console.log("Try to find a BigInt in the bundle cache....");
	const results = [];
	findBigintInCache("", bundle.cache, results);
	console.log("Results: ", results);
	throw error;
}


function findBigintInCache(path, cachedObject, results) {
	
	//console.log("Try to find a BigInt in the bundle cache: ", path);

	if (cachedObject === null || cachedObject === undefined) {
		return;
	}

	switch(typeof cachedObject) {
		case "bigint":
			results.push(`${path} is a bigint: ` + cachedObject);
			break;

		case "number":
		case "boolean":
		case "string":
		case "symbol":
		case "undefined":
			break;

		case "object": 
			if (cachedObject instanceof Date) {
				return;
			}
			if (Array.isArray(cachedObject)) {
				for (let i=0; i < cachedObject.length; i++) {
					findBigintInCache(`${path}[${i}]`,cachedObject[i], results);
				}	
			} else {
				const keys = Object.getOwnPropertyNames(cachedObject);
				for (const key of keys) {
					const value = cachedObject[key];
					findBigintInCache(`${path}.${key}`, value, results);
				}
			}
			break;
	}
}

And this was the result:

Results:  [
  '.modules[193].ast.body[3].declaration.body.body[3].value.body.body[7].declarations[0].init.value is a bigint: 97',
  '.modules[193].ast.body[3].declaration.body.body[3].value.body.body[10].argument.right.value is a bigint: 1'
]

In my case this was the problematic code:

private validateChecksum(iban: string): boolean {
	const bban = iban.substring(4);
	const country = iban.substring(0, 2);
	const checkSum = iban.substring(2, 4);

	let sb = bban;
	sb += this.indexOf(country[0]);
	sb += this.indexOf(country[1]);
	sb += checkSum;

	const MODULO = 97n;
	const bigInt = BigInt(sb);
	const mod = bigInt %  MODULO;
	return mod === 1n;
}

BigInt literals like 1n or 97n produce this kind or error. Replace them with BigInt(1) (resp. BigInt(97)) and the problem is gone.

Hope that helps.....

@ssams
Copy link

ssams commented Apr 5, 2023

just stumbled across this, with the confusing behavior that it didn't compile locally but working without issues in the CI build ... as ng-packagr automatically disables the cache in CI environments, the error may be hidden / not reproducible in some environments.

const isCI = ciEnv?.toLowerCase() === 'true' || ciEnv === '1';
const { cacheEnabled = !isCI, cacheDirectory = findCachePath() } = options;

the issue is also triggered by BigInt literal in my code (same error message as in the original description), I can confirm replacing 1n with BigInt(1) as suggested by @rehdie as workaround. Alternatively disabling the Angular cache (and therefore also ng-packagr cache apparently) worked, could be also another reason why it sometimes may not be reproducible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants