nodejs / nodejs/orchestrion-js
Mutating traced function arguments in channel subscriber
@simon-id is already working on this.
Since Jun 12, 2025.
- Dominant language
- JavaScript
- Stars
- 24
- Forks
- 11
- PR merge metrics
- No merged PRs in 30d
Description
Thank you @sabrenner for discovering, reporting, and helping with this!
Sometimes we want to replace one of the arguments of the traced function, from inside of the channel subscriber. This is usually the case when we want to replace the callback by our own, to be able to execute code before the real callback is called:
function fetch (data, cb) {
cb(data)
}
This gets rewritten into:
function fetch(data, cb) {
const traced = ()=>{
cb(data);
};
if (!tr_ch_apm$param_mutation.hasSubscribers) return traced();
return tr_ch_apm$param_mutation.traceSync(traced, {
arguments,
self: this
});
}
and we can then run:
channel.subscribe((context) => {
const originalCb = context.arguments[1]
const wrappedCb = function (data) {
// ... do something before real callback is called
return originalCb.apply(this, arguments)
}
context.arguments[1] = wrappedCb
})
This already work because the named arguments of fetch() are updated when the arguments object is mutated.
But because of ECMA-262 specification 10.2.11 22.a.i, it does NOT work in strict-mode functions, or in functions with "complex" arguments (ie: rest parameters, default values, destructured parameters):
22. If argumentsObjectNeeded is true, then
a. If strict is true or simpleParameterList is false, then
i. Let ao be CreateUnmappedArgumentsObject(argumentsList).
b. Else,
i. NOTE: A mapped argument object is only provided for non-strict functions that don't have a rest parameter, any parameter default value initializers, or any destructured parameters.
ii. Let ao be CreateMappedArgumentsObject(func, formals, argumentsList, env).
So if we replace the initial code with something as trivial as:
function fetch ({ data }, cb) { // same thing with `...data` or `data = 'default'` or with 'use strict'
cb(data)
}
the subscriber cannot replace the callback anymore.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.