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;
};
}