-
-
Notifications
You must be signed in to change notification settings - Fork 33.4k
Open
Labels
diagnostics_channelIssues and PRs related to diagnostics channelIssues and PRs related to diagnostics channel
Description
Version
18.19.0+
Platform
All
Subsystem
diagnostics_channel
What steps will reproduce the bug?
We received a report about an openai method crashing that's been wrapped with tracingChannel.tracePromise
. After some digging, I see the issues is here. OpenAI creates a custom promise and it's getting stripped in tracePromise. This is a distilled repro case to show the issue.
import assert from 'node:assert';
import { tracingChannel } from 'node:diagnostics_channel';
const channel = tracingChannel('custom-promise')
channel.subscribe({
asyncStart(data) {
}
})
class CustomPromise {
constructor(executor) {
this.state = 'pending'; // Possible states: 'pending', 'fulfilled', 'rejected'
this.value = undefined; // Will hold the result or error
this.successCallbacks = [];
this.errorCallbacks = [];
// Executor is the function passed to the promise
try {
executor(this._resolve, this._reject);
} catch (error) {
this._reject(error);
}
}
// Custom resolve function
_resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.successCallbacks.forEach(callback => callback(this.value));
}
}
// Custom reject function
_reject = (error) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = error;
this.errorCallbacks.forEach(callback => callback(this.value));
}
}
// Then method to handle successful promise resolution
then(successCallback) {
if (this.state === 'fulfilled') {
successCallback(this.value);
} else if (this.state === 'pending') {
this.successCallbacks.push(successCallback);
}
return this; // Allows chaining 🔄
}
// Catch method to handle promise rejection
catch(errorCallback) {
if (this.state === 'rejected') {
errorCallback(this.value);
} else if (this.state === 'pending') {
this.errorCallbacks.push(errorCallback);
}
return this; // Allows chaining 🔄
}
}
function test(arg) {
return new CustomPromise((resolve) => {
setTimeout(() => {
resolve(arg)
}, 100)
})
}
const arg = 'test'
const promise = channel.tracePromise(test, { ctx: true}, this, arg)
assert.equal(promise.constructor.name, 'CustomPromise')
const result = await promise
assert.equal(result, arg)
How often does it reproduce? Is there a required condition?
Every time
What is the expected behavior? Why is that the expected behavior?
To properly return the custom promise
What do you see instead?
It returns a native Promise instead
Additional information
I could workaround this by using traceSync
and propagating the promise myself, but I'd prefer that the API does the right thing.
Metadata
Metadata
Assignees
Labels
diagnostics_channelIssues and PRs related to diagnostics channelIssues and PRs related to diagnostics channel