@@ -10,6 +10,8 @@ const {
1010 ObjectDefineProperty,
1111 ObjectGetPrototypeOf,
1212 ObjectSetPrototypeOf,
13+ Promise,
14+ PromisePrototypeThen,
1315 ReflectApply,
1416 SafeFinalizationRegistry,
1517 SafeMap,
@@ -26,6 +28,9 @@ const {
2628} = require ( 'internal/validators' ) ;
2729
2830const { triggerUncaughtException } = internalBinding ( 'errors' ) ;
31+ const { isPromise } = require ( 'internal/util/types' ) ;
32+
33+ const PromisePrototype = Promise . prototype ;
2934
3035const dc_binding = internalBinding ( 'diagnostics_channel' ) ;
3136const { subscribers : subscriberCounts } = dc_binding ;
@@ -369,16 +374,20 @@ class TracingChannel {
369374
370375 const { start, end, asyncStart, asyncEnd, error } = this ;
371376
372- function reject ( err ) {
377+ function onReject ( err ) {
373378 context . error = err ;
374379 error . publish ( context ) ;
375380 asyncStart . publish ( context ) ;
376381 // TODO: Is there a way to have asyncEnd _after_ the continuation?
377382 asyncEnd . publish ( context ) ;
383+ }
384+
385+ function onRejectWithRethrow ( err ) {
386+ onReject ( err ) ;
378387 throw err ;
379388 }
380389
381- function resolve ( result ) {
390+ function onResolve ( result ) {
382391 context . result = result ;
383392 asyncStart . publish ( context ) ;
384393 // TODO: Is there a way to have asyncEnd _after_ the continuation?
@@ -396,7 +405,17 @@ class TracingChannel {
396405 context . result = result ;
397406 return result ;
398407 }
399- return result . then ( resolve , reject ) ;
408+ // isPromise() matches sub-classes, but we need to match only direct
409+ // instances of the native Promise type to safely use PromisePrototypeThen.
410+ if ( isPromise ( result ) && ObjectGetPrototypeOf ( result ) === PromisePrototype ) {
411+ return PromisePrototypeThen ( result , onResolve , onRejectWithRethrow ) ;
412+ }
413+ // For non-native thenables, subscribe to the result but return the
414+ // original thenable so the consumer can continue handling it directly.
415+ // Non-native thenables don't have unhandledRejection tracking, so
416+ // swallowing the rejection here doesn't change existing behaviour.
417+ result . then ( onResolve , onReject ) ;
418+ return result ;
400419 } catch ( err ) {
401420 context . error = err ;
402421 error . publish ( context ) ;
0 commit comments