Skip to content

Commit

Permalink
Catch down network exception and non-object responses in fetch (#2492)
Browse files Browse the repository at this point in the history
* Catch down network exception and non-object responses in fetch

* Handle more unexpected data types

* Address comments on #2492 (#2501)

* Adjust handling of TerminusCollection items lacking useful data

* Add comment clarifying handling of null response object

* Variable and comment cleanup

---------

Co-authored-by: Brian Weaver <[email protected]>
Co-authored-by: Brian Weaver <[email protected]>
  • Loading branch information
3 people authored Sep 27, 2023
1 parent 6faf12f commit 55cc06e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
33 changes: 32 additions & 1 deletion src/Collections/TerminusCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
use Pantheon\Terminus\Models\TerminusModel;
use Pantheon\Terminus\Request\RequestAwareInterface;
use Pantheon\Terminus\Request\RequestAwareTrait;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;

/**
* Class TerminusCollection
* @package Pantheon\Terminus\Collections
*/
abstract class TerminusCollection implements ContainerAwareInterface, RequestAwareInterface
abstract class TerminusCollection implements ContainerAwareInterface, RequestAwareInterface, LoggerAwareInterface
{
use ContainerAwareTrait;
use RequestAwareTrait;
use LoggerAwareTrait;

/**
* @var array
Expand Down Expand Up @@ -91,6 +94,34 @@ public function all()
public function fetch()
{
foreach ($this->getData() as $id => $model_data) {
if (!is_object($model_data)) {
// This should always be an object, however occasionally it is returning as a string
// We need more information about what it is and to handle the error
$model_data_str = print_r($model_data, true);
$error_maxlength = 250;
if (is_string($model_data_str) && strlen($model_data_str) > $error_maxlength) {
$model_data_str = substr($model_data_str, 0, $error_maxlength) . ' ...';
}
$error_message = "Fetch failed {file}:{line} \$model_data expected as object but returned as {type}.";
$error_message .= "\nUnexpected value: {model_data_str}";
$trace = debug_backtrace();
$context = [
'file' => $trace[0]['file'],
'line' => $trace[0]['line'],
'type' => gettype($model_data),
'model_data_str' => $model_data_str
];

// verbose logging for debugging
$this->logger->debug($error_message, $context);

// less information for more user-facing messages, but a problem has occurred and we're skipping this
// item so we should still surface a user-facing message
$this->logger->warning("Model data missing for {id}", ['id' => $id,]);

// skip this item since it lacks useful data
continue;
}
if (!isset($model_data->id)) {
$model_data->id = $id;
}
Expand Down
11 changes: 10 additions & 1 deletion src/Request/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,21 @@ private function createRetryDecider(): callable
}
}

// Response can be null if there is a network disconnect. Get a different error message in that case.
if (is_object($response) && is_object($response->getBody()) && $response->getBody()->getContents() !== '') {
$error = $response->getBody()->getContents();
} elseif (null !== $exception && '' != $exception->getMessage()) {
$error = $exception->getMessage();
} else {
$error = "Undefined";
}

$this->logger->error(
"HTTP request {method} {uri} has failed with error {error}.",
[
'method' => $request->getMethod(),
'uri' => $request->getUri(),
'error' => $response->getBody()->getContents(),
'error' => $error,
]
);

Expand Down

0 comments on commit 55cc06e

Please sign in to comment.