diagnostics_channel: ensure tracePromise consistency with non-Promises
Merged
RE
7mo ago+143+143+012345678901234567890123456789-20-20-01234567890123456789
tracingChannel.tracePromise() is documented in the source code (albeit not in the docs) to accept functions that return non-Promise thenables. However, it currently has some wonky behaviour when the return value isn't a native Promise, and also in the undocumented case where the return value isn't promise-like at all.
What gets returned by tracePromise() is highly dependent on whether the tracing channel has active subscribers or not:
result type |
Without subscribers | With subscribers | ||
|---|---|---|---|---|
| Return value | Return type | Return value | Return type | |
| Native Promise | result |
Native Promise | result.then(...) |
Native Promise |
| Custom thenable | result |
Custom thenable | Promise.resolve(result).then(...) |
Native Promise |
| Non-thenable | result |
Non-thenable | Promise.resolve(result).then(...) |
Native Promise |
The major inconsistencies are:
- If the wrapped function returns a custom thenable, then it will either be returned as a custom thenable or wrapped in a native Promise, depending on whether there are active subscribers.
- If the wrapped function returns a non-thenable, then it will either be returned verbatim or wrapped in a resolved native Promise, depending on whether there are active subscribers.
- In the case where the wrapped function synchronously returns a non-thenable, then tracePromise produces
asyncStart/asyncEndevents, despite no asynchronous execution. On the other hand, if the wrapped function throws synchronously, these events are not produced.
This PR makes some changes to the non-Promise cases to make the behaviours consistent.
- If the wrapped function returns either a Promise or a custom thenable, then the value returned by tracePromise will have the same type: either the original value (if no subscribers) or the value of
result.then(...)(if active subscribers). - If the wrapped function returns a non-thenable result, then it is returned verbatim, and a warning is emitted. No
asyncStartorasyncEndevents are produced.
result type |
Without subscribers | With subscribers | ||
|---|---|---|---|---|
| Return value | Return type | Return value | Return type | |
| Native Promise | result |
Native Promise | result.then(...) |
Native Promise |
| Custom thenable | result |
Custom thenable | result.then(...) |
Custom thenable |
| Non-thenable | result |
Non-thenable | result |
Non-thenable |
Fixes: #59936