Passing an async function as a callback causes the error stack trace to be lost

Missing stack trace has nothing to do with Promises. Write the same code that has functions calling each other in synchronous way and you will observe exactly the same behavior i.e. loosing complete stack trace data when rethrowing new Error. It is only Error object that offers stack access. It in turn is backed by native code (like this of V8 engine) responsible for capturing stack trace of crossed stack frames. To make it worse each time you create Error object it captures stack from this point across the stackframes (at least it is observable in browser, nodejs implementation may differ). So that if you catch and retrow different Error object then its stack trace is visible on top of bubbling exception. Missing exceptions chaining for Error (no way to wrap new exception around caught one) makes it hard to fill these gaps. More interesting is that ECMA-262 spec chapter 19.5 does not introduce Error.prototype.stack property at all, in MDN in turn you find stack property is JS engine non-standard extension.

EDIT: Regarding missing "everything" function on stack it is side effect of how engine translates "async/await" into microtask calls and who is really calling specific callbacks. Refer to V8 engine team explanation as well as their zero-cost async stack traces document covering details. NodeJS starting from version 12.x will incorporate more cleaner stack traces, available with --async-stack-traces option offered by V8 engine.