private function wrapHandler()

in src/OpenSearch/Connections/Connection.php [253:345]


    private function wrapHandler(callable $handler): callable
    {
        return function (array $request, Connection $connection, Transport $transport = null, $options) use ($handler) {
            $this->lastRequest = [];
            $this->lastRequest['request'] = $request;

            // Send the request using the wrapped handler.
            $response =  Core::proxy(
                $handler($request),
                function ($response) use ($connection, $transport, $request, $options) {
                    $this->lastRequest['response'] = $response;

                    if (isset($response['error']) === true) {
                        if ($response['error'] instanceof ConnectException || $response['error'] instanceof RingException) {
                            $this->log->warning("Curl exception encountered.");

                            $exception = $this->getCurlRetryException($request, $response);

                            $this->logRequestFail($request, $response, $exception);

                            $node = $connection->getHost();
                            $this->log->warning("Marking node $node dead.");
                            $connection->markDead();

                            // If the transport has not been set, we are inside a Ping or Sniff,
                            // so we don't want to retrigger retries anyway.
                            //
                            // TODO this could be handled better, but we are limited because connectionpools do not
                            // have access to Transport.  Architecturally, all of this needs to be refactored
                            if (isset($transport) === true) {
                                $transport->connectionPool->scheduleCheck();

                                $neverRetry = isset($request['client']['never_retry']) ? $request['client']['never_retry'] : false;
                                $shouldRetry = $transport->shouldRetry($request);
                                $shouldRetryText = ($shouldRetry) ? 'true' : 'false';

                                $this->log->warning("Retries left? $shouldRetryText");
                                if ($shouldRetry && !$neverRetry) {
                                    return $transport->performRequest(
                                        $request['http_method'],
                                        $request['uri'],
                                        [],
                                        $request['body'],
                                        $options
                                    );
                                }
                            }

                            $this->log->warning("Out of retries, throwing exception from $node");
                            // Only throw if we run out of retries
                            throw $exception;
                        } else {
                            // Something went seriously wrong, bail
                            $exception = new TransportException($response['error']->getMessage());
                            $this->logRequestFail($request, $response, $exception);
                            throw $exception;
                        }
                    } else {
                        $connection->markAlive();

                        if (isset($response['headers']['Warning'])) {
                            $this->logWarning($request, $response);
                        }
                        if (isset($response['body']) === true) {
                            $response['body'] = stream_get_contents($response['body']);
                            $this->lastRequest['response']['body'] = $response['body'];
                        }

                        if ($response['status'] >= 400 && $response['status'] < 500) {
                            $ignore = $request['client']['ignore'] ?? [];
                            // Skip 404 if succeeded true in the body (e.g. clear_scroll)
                            $body = $response['body'] ?? '';
                            if (strpos($body, '"succeeded":true') !== false) {
                                $ignore[] = 404;
                            }
                            $this->process4xxError($request, $response, $ignore);
                        } elseif ($response['status'] >= 500) {
                            $ignore = $request['client']['ignore'] ?? [];
                            $this->process5xxError($request, $response, $ignore);
                        }

                        // No error, deserialize
                        $response['body'] = $this->serializer->deserialize($response['body'], $response['transfer_stats']);
                    }
                    $this->logRequestSuccess($request, $response);

                    return isset($request['client']['verbose']) && $request['client']['verbose'] === true ? $response : $response['body'];
                }
            );

            return $response;
        };
    }