function _applyRecorderSegment({ context, boundThis, args, segDesc, shim, fn, name }) {
  const { segment, transaction } = context
  let error = null
  let promised = false
  let ret
  try {
    ret = shim.applyContext({
      func: fn,
      context,
      full: true,
      boundThis,
      args,
      inContextCB: segDesc.inContext
    })
    if (segDesc.after && segDesc.promise && shim.isPromise(ret)) {
      promised = true
      return ret.then(
        function onThen(val) {
          segment.touch()
          // passing in error as some instrumentation checks if it's not equal to `null`
          segDesc.after({ shim, fn, name, error, result: val, segment, transaction })
          return val
        },
        function onCatch(err) {
          segment.touch()
          segDesc.after({ shim, fn, name, error: err, segment, transaction })
          throw err // NOTE: This is not an error from our instrumentation.
        }
      )
    }
    return ret
  } catch (err) {
    error = err
    throw err // Just rethrowing this error, not our error!
  } finally {
    if (segDesc.after && (error || !promised)) {
      segDesc.after({ shim, fn, name, error, result: ret, segment, transaction })
    }
  }
}
Binds active segment to wrapped function.  Calls the after hook if it exists on spec

@private
@param {object} params to function
@param {Context} params.context agent context to run in
@param {Array} params.args The arguments to the wrapped callback
@param {Spec} params.segDesc Segment descriptor spec
@param {Shim} params.shim instance of shim
@param {Function} params.fn function being wrapped
@param {*} params.boundThis the function context to run in
@param {string} params.name name of function being wrapped
@returns {*} return value of wrapped function