Custom error cloning to fix node v21 issue #390
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes a
Hoek.clone(err)
issue introduced in node v21.The problem
Node 21 updates the V8 engine to 11.8, which includes a patch from v11.5.1 that changes how the
Error.stack
property works.With this patch, a copied
err.stack
descriptor will no longer return thestack
of the source error, but always returnundefined
. This breaks Boom, where it relies on clone() to fully work.This manifestation of this issue was reported on discord.
The solution
The only way to copy a working stack descriptor in node 21, is to used the
structuredClone()
method. This is a platform method that uses an algorithm from the HTML spec to create a "clone". Only the "name", "message", "cause", and "stack" properties are transferred, and the prototype is set to a standardError
. See the serialization algorithm step 17 which deals with[[ErrorData]]
objects.I use
structuredClone()
to create the base object, and then pass it through the standard recursive object cloner to clone all properties except thestack
property. This preserves the existing behaviour, including for weird corner cases.This PR will only work with node >= v17.0.0, which is when
structuredClone()
was added. Given that every node release <18 is no longer supported, I don't want to spend energy fixing this, and expect that this fix can be part of a new breaking change release. Or is the current release expected to support node v21?