function call(handler, err, req, res, _next) {
    var arity = handler.length;
    var hasError = err === false || Boolean(err);

    // Meassure handler timings
    // _name is assigned in the server and router
    req._currentHandler = handler._name;
    req.startHandlerTimer(handler._name);

    function next(nextErr) {
        req.endHandlerTimer(handler._name);
        _next(nextErr, req, res);
    }

    function resolve(value) {
        if (value && req.log) {
            // logs resolved value
            req.log.warn(
                { value },
                'Discarded returned value from async handler'
            );
        }

        return next();
    }

    function reject(error) {
        if (!(error instanceof Error)) {
            error = new customErrorTypes.AsyncError(
                {
                    info: {
                        cause: error,
                        handler: handler._name,
                        method: req.method,
                        path: req.path ? req.path() : undefined
                    }
                },
                'Async middleware rejected without an error'
            );
        }
        return next(error);
    }

    if (hasError && arity === 4) {
        // error-handling middleware
        handler(err, req, res, next);
        return;
    } else if (!hasError && arity < 4) {
        // request-handling middleware
        process.nextTick(function nextTick() {
            const result = handler(req, res, next);
            if (result && typeof result.then === 'function') {
                result.then(resolve, reject);
            }
        });
        return;
    }

    // continue
    next(err);
}
Invoke a handler.

@private
@param {Function} handler - handler function
@param {Error|false|*} err - error, abort when true value or false
@param {Request} req - request
@param {Response} res - response
@param {Function} _next - next handler
@returns {undefined} no return value