fix(browser): keep the merging object when setBindings is used on the root logger - #2512
fix(browser): keep the merging object when setBindings is used on the root logger#2512dylanpulver wants to merge 1 commit into
Conversation
… root logger asObject() used _childLevel to count how many leading arguments are prepended bindings, but the arguments are prepended from getBindingChain(), which also includes the logger's own bindings. Until setBindings() was added to the browser logger only children could have bindings, so the two counts happened to agree. Once the root logger has bindings the chain is one longer than the count, so the caller's merging object is consumed as a binding and their message is discarded. Record the length of the chain that is actually prepended instead. The naughty-numbers guard test is re-pointed at the field the merge loop now reads so it keeps guarding rather than passing vacuously.
kilisamemarisaaa
left a comment
There was a problem hiding this comment.
Tested this head (d57cf8f) on Windows with Node 24.12.0.
The focused browser-set-bindings and browser suites passed all 217 assertions. I also exercised multiple root updates, child setBindings(), children created before and after a parent update, grandchild precedence, and asObjectBindingsOnly; the child-before-parent case matches the Node implementation's fixed-at-creation semantics.
The full runtime suite reached 537 passing / 4 skipped with one environment-only failure: current main's transpile helper invokes Unix mv on Windows, so the generated to-file-transport.es2017.cjs fixture was missing (the existing #2499 addresses that). After generating the same three fixtures with PowerShell, the affected bundler test passed 3/3. Lint also passed before the known transpile gate.
I did not find a regression in the _bindingsDepth change.
setBindings()on the root browser logger destroys the merging object of every later call:The fields and the message are both lost.
asObject()takes the number of prepended bindings from_childLevel, but they are prepended fromgetBindingChain(), which also counts the logger's own bindings. Before #2471 only children had bindings, so the two agreed by accident. Children created after thesetBindings()call are affected too.So the fix records the length of the chain
set()actually prepends. RecomputinggetBindingChain()insideasObject()looks equivalent but isn't: the chain is captured in a closure, so a child created beforesetBindings()would over-merge and swallow a second object argument.Not fixed here, and I'd rather ask than guess.
setBindings()pushesnewBindingsinto_logEvent.bindingswhile storing a different merged object, sotransmit's reference filter misses it and those bindings also appear inlogEvent.messages. What that array should hold for a root logger isn't obvious to me.All six existing
browser-set-bindingstests log with a string first argument, which is why this was invisible. Added four object-first cases; all four fail with thebrowser.jschange reverted. The naughty-numbers guard test is re-pointed at the field the loop now reads so it keeps guarding.npm run test-cigreen, 381 assertions vs 369 before.