@@ -10,6 +10,9 @@ const {
1010 ObjectDefineProperty,
1111 ObjectGetPrototypeOf,
1212 ObjectSetPrototypeOf,
13+ Promise,
14+ PromisePrototype,
15+ PromisePrototypeThen,
1316 ReflectApply,
1417 SafeFinalizationRegistry,
1518 SafeMap,
@@ -26,6 +29,7 @@ const {
2629} = require ( 'internal/validators' ) ;
2730
2831const { triggerUncaughtException } = internalBinding ( 'errors' ) ;
32+ const { isPromise } = require ( 'internal/util/types' ) ;
2933
3034const dc_binding = internalBinding ( 'diagnostics_channel' ) ;
3135const { subscribers : subscriberCounts } = dc_binding ;
@@ -369,16 +373,20 @@ class TracingChannel {
369373
370374 const { start, end, asyncStart, asyncEnd, error } = this ;
371375
372- function reject ( err ) {
376+ function onReject ( err ) {
373377 context . error = err ;
374378 error . publish ( context ) ;
375379 asyncStart . publish ( context ) ;
376380 // TODO: Is there a way to have asyncEnd _after_ the continuation?
377381 asyncEnd . publish ( context ) ;
382+ }
383+
384+ function onRejectWithRethrow ( err ) {
385+ onReject ( err ) ;
378386 throw err ;
379387 }
380388
381- function resolve ( result ) {
389+ function onResolve ( result ) {
382390 context . result = result ;
383391 asyncStart . publish ( context ) ;
384392 // TODO: Is there a way to have asyncEnd _after_ the continuation?
@@ -396,7 +404,17 @@ class TracingChannel {
396404 context . result = result ;
397405 return result ;
398406 }
399- return result . then ( resolve , reject ) ;
407+ // isPromise() matches sub-classes, but we need to match only direct
408+ // instances of the native Promise type to safely use PromisePrototypeThen.
409+ if ( isPromise ( result ) && ObjectGetPrototypeOf ( result ) === PromisePrototype ) {
410+ return PromisePrototypeThen ( result , onResolve , onRejectWithRethrow ) ;
411+ }
412+ // For non-native thenables, subscribe to the result but return the
413+ // original thenable so the consumer can continue handling it directly.
414+ // Non-native thenables don't have unhandledRejection tracking, so
415+ // swallowing the rejection here doesn't change existing behaviour.
416+ result . then ( onResolve , onReject ) ;
417+ return result ;
400418 } catch ( err ) {
401419 context . error = err ;
402420 error . publish ( context ) ;
0 commit comments