diff --git a/src/future/aws/PhutilAWSException.php b/src/future/aws/PhutilAWSException.php index 7646c7b6..ac21ba12 100644 --- a/src/future/aws/PhutilAWSException.php +++ b/src/future/aws/PhutilAWSException.php @@ -49,4 +49,24 @@ final class PhutilAWSException extends Exception { return $this->httpStatus; } + public function isNotFoundError() { + if ($this->hasErrorCode('InvalidVolume.NotFound')) { + return true; + } + + return false; + } + + private function hasErrorCode($code) { + $errors = idx($this->params, 'Errors', array()); + + foreach ($errors as $error) { + if ($error[0] === $code) { + return true; + } + } + + return false; + } + } diff --git a/src/future/aws/PhutilAWSFuture.php b/src/future/aws/PhutilAWSFuture.php index 16fd3632..90395b4b 100644 --- a/src/future/aws/PhutilAWSFuture.php +++ b/src/future/aws/PhutilAWSFuture.php @@ -142,6 +142,7 @@ abstract class PhutilAWSFuture extends FutureProxy { try { $xml = @(new SimpleXMLElement($body)); } catch (Exception $ex) { + phlog($ex); $xml = null; } @@ -155,9 +156,28 @@ abstract class PhutilAWSFuture extends FutureProxy { ); if ($xml) { $params['RequestID'] = $xml->RequestID[0]; - $errors = array($xml->Error); - foreach ($errors as $error) { - $params['Errors'][] = array($error->Code, $error->Message); + + // NOTE: The S3 and EC2 APIs return slightly different error responses. + + // In S3 responses, there's a simple top-level "" element. + $s3_error = $xml->Error; + if ($s3_error) { + $params['Errors'][] = array( + phutil_string_cast($s3_error->Code), + phutil_string_cast($s3_error->Message), + ); + } + + // In EC2 responses, there's an "" element with "" + // children. + $ec2_errors = $xml->Errors[0]; + if ($ec2_errors) { + foreach ($ec2_errors as $error) { + $params['Errors'][] = array( + phutil_string_cast($error->Code), + phutil_string_cast($error->Message), + ); + } } }