function transactionNestProxy(type, handler) {
  if (handler === undefined && typeof type === 'function') {
    handler = type
    type = undefined
  }
  // if there's no handler, there's nothing to proxy.
  if (typeof handler !== 'function') {
    return handler
  }

  const tracer = this
  const wrapped = function wrapTransactionInvocation() {
    if (!tracer.agent.canCollectData()) {
      return handler.apply(this, arguments)
    }

    // don't nest transactions, reuse existing ones
    let context = tracer.getContext()
    const transaction = tracer.getTransaction()

    let createNew = false

    if (!transaction || transaction.type !== type) {
      createNew = true
    }

    if (createNew) {
      const transaction = new Transaction(tracer.agent)
      transaction.type = type
      context = context.enterTransaction(transaction)
    }

    return tracer.bindFunction(handler, context).apply(this, arguments)
  }

  wrapped[symbols.original] = handler

  return wrapped
}
Use transactionNestProxy to wrap a closure that is a top-level handler that
is meant to start transactions. This wraps the first half of asynchronous
handlers. Use bindFunction to wrap handler callbacks. This detects to see
if there is an in play segment and uses that as the root instead of
transaction.trace.root.

@param {string} type - Type of transaction to create. 'web' or 'bg'.
@param {Function} handler - Generator to proxy.
@returns {Function} Proxy.