← All changes
|
includes/sdk/google/google/gax/src/ApiException.php
+58
-27
1.2.7
→
1.4.2
View file →
| @@ -29,15 +29,14 @@ | ||
| 29 | 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 30 | 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 31 | 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 32 | 32 | */ |
| 33 | -namespace Dudlewebs\WPMCS\Google\ApiCore; | |
| 33 | +namespace Dudlewebs\WPMCS\GCP\Google\ApiCore; | |
| 34 | 34 | |
| 35 | 35 | use Exception; |
| 36 | -use Dudlewebs\WPMCS\Google\Protobuf\Internal\RepeatedField; | |
| 37 | -use Dudlewebs\WPMCS\Google\Rpc\Status; | |
| 38 | -use Dudlewebs\WPMCS\GuzzleHttp\Exception\RequestException; | |
| 39 | -use Dudlewebs\WPMCS\Google\ApiCore\Testing\MockStatus; | |
| 36 | +use Dudlewebs\WPMCS\GCP\Google\Protobuf\RepeatedField; | |
| 37 | +use Dudlewebs\WPMCS\GCP\Google\Rpc\Status; | |
| 38 | +use Dudlewebs\WPMCS\GCP\GuzzleHttp\Exception\RequestException; | |
| 40 | 39 | use stdClass; |
| 41 | 40 | /** |
| 42 | 41 | * Represents an exception thrown during an RPC. |
| 43 | 42 | */ |
| @@ -46,8 +45,9 @@ | ||
| 46 | 45 | private $status; |
| 47 | 46 | private $metadata; |
| 48 | 47 | private $basicMessage; |
| 49 | 48 | private $decodedMetadataErrorInfo; |
| 49 | + private array $protobufErrors; | |
| 50 | 50 | /** |
| 51 | 51 | * ApiException constructor. |
| 52 | 52 | * @param string $message |
| 53 | 53 | * @param int $code |
| @@ -57,9 +57,9 @@ | ||
| 57 | 57 | * @type array|null $metadata |
| 58 | 58 | * @type string|null $basicMessage |
| 59 | 59 | * } |
| 60 | 60 | */ |
| 61 | - public function __construct(string $message, int $code, string $status = null, array $optionalArgs = []) | |
| 61 | + public function __construct(string $message, int $code, ?string $status = null, array $optionalArgs = [], array $protobufErrors = []) | |
| 62 | 62 | { |
| 63 | 63 | $optionalArgs += ['previous' => null, 'metadata' => null, 'basicMessage' => $message]; |
| 64 | 64 | parent::__construct($message, $code, $optionalArgs['previous']); |
| 65 | 65 | $this->status = $status; |
| @@ -67,8 +67,9 @@ | ||
| 67 | 67 | $this->basicMessage = $optionalArgs['basicMessage']; |
| 68 | 68 | if ($this->metadata) { |
| 69 | 69 | $this->decodedMetadataErrorInfo = self::decodeMetadataErrorInfo($this->metadata); |
| 70 | 70 | } |
| 71 | + $this->protobufErrors = $protobufErrors; | |
| 71 | 72 | } |
| 72 | 73 | public function getStatus() |
| 73 | 74 | { |
| 74 | 75 | return $this->status; |
| @@ -86,9 +87,9 @@ | ||
| 86 | 87 | private static function decodeMetadataErrorInfo(array $metadata) |
| 87 | 88 | { |
| 88 | 89 | $details = []; |
| 89 | 90 | // ApiExceptions created from RPC status have metadata that is an array of objects. |
| 90 | - if (is_object(reset($metadata))) { | |
| 91 | + if (\is_object(\reset($metadata))) { | |
| 91 | 92 | $metadataRpcStatus = Serializer::decodeAnyMessages($metadata); |
| 92 | 93 | $details = self::containsErrorInfo($metadataRpcStatus); |
| 93 | 94 | } elseif (self::containsErrorInfo($metadata)) { |
| 94 | 95 | $details = self::containsErrorInfo($metadata); |
| @@ -123,15 +124,24 @@ | ||
| 123 | 124 | { |
| 124 | 125 | return $this->decodedMetadataErrorInfo ? $this->decodedMetadataErrorInfo['errorInfoMetadata'] : null; |
| 125 | 126 | } |
| 126 | 127 | /** |
| 128 | + * Returns the unserialized errors | |
| 129 | + * @return array | |
| 130 | + */ | |
| 131 | + public function getErrorDetails() : array | |
| 132 | + { | |
| 133 | + return $this->protobufErrors; | |
| 134 | + } | |
| 135 | + /** | |
| 127 | 136 | * @param stdClass $status |
| 128 | 137 | * @return ApiException |
| 129 | 138 | */ |
| 130 | 139 | public static function createFromStdClass(stdClass $status) |
| 131 | 140 | { |
| 132 | - $metadata = property_exists($status, 'metadata') ? $status->metadata : null; | |
| 133 | - return self::create($status->details, $status->code, $metadata, Serializer::decodeMetadata((array) $metadata)); | |
| 141 | + $metadata = \property_exists($status, 'metadata') ? $status->metadata : null; | |
| 142 | + $errors = []; | |
| 143 | + return self::create($status->details, $status->code, $metadata, Serializer::decodeMetadata((array) $metadata, $errors), $errors); | |
| 134 | 144 | } |
| 135 | 145 | /** |
| 136 | 146 | * @param string $basicMessage |
| 137 | 147 | * @param int $rpcCode |
| @@ -138,11 +148,12 @@ | ||
| 138 | 148 | * @param array|null $metadata |
| 139 | 149 | * @param Exception $previous |
| 140 | 150 | * @return ApiException |
| 141 | 151 | */ |
| 142 | - public static function createFromApiResponse($basicMessage, $rpcCode, array $metadata = null, Exception $previous = null) | |
| 152 | + public static function createFromApiResponse($basicMessage, $rpcCode, ?array $metadata = null, ?Exception $previous = null) | |
| 143 | 153 | { |
| 144 | - return self::create($basicMessage, $rpcCode, $metadata, Serializer::decodeMetadata((array) $metadata), $previous); | |
| 154 | + $errors = []; | |
| 155 | + return self::create($basicMessage, $rpcCode, $metadata, Serializer::decodeMetadata((array) $metadata, $errors), $errors, $previous); | |
| 145 | 156 | } |
| 146 | 157 | /** |
| 147 | 158 | * For REST-based responses, the metadata does not need to be decoded. |
| 148 | 159 | * |
| @@ -151,11 +162,11 @@ | ||
| 151 | 162 | * @param array|null $metadata |
| 152 | 163 | * @param Exception $previous |
| 153 | 164 | * @return ApiException |
| 154 | 165 | */ |
| 155 | - public static function createFromRestApiResponse($basicMessage, $rpcCode, array $metadata = null, Exception $previous = null) | |
| 166 | + public static function createFromRestApiResponse($basicMessage, $rpcCode, ?array $metadata = null, ?Exception $previous = null) | |
| 156 | 167 | { |
| 157 | - return self::create($basicMessage, $rpcCode, $metadata, is_null($metadata) ? [] : $metadata, $previous); | |
| 168 | + return self::create($basicMessage, $rpcCode, $metadata, \is_null($metadata) ? [] : $metadata, self::decodeMetadataToProtobufErrors($metadata ?? []), $previous); | |
| 158 | 169 | } |
| 159 | 170 | /** |
| 160 | 171 | * Checks if decoded metadata includes errorInfo message. |
| 161 | 172 | * If errorInfo is set, it will always contain `reason`, `domain`, and `metadata` keys. |
| @@ -187,26 +198,54 @@ | ||
| 187 | 198 | * @param string $basicMessage |
| 188 | 199 | * @param int $rpcCode |
| 189 | 200 | * @param iterable|null $metadata |
| 190 | 201 | * @param array $decodedMetadata |
| 202 | + * @param array|null $protobufErrors | |
| 191 | 203 | * @param Exception|null $previous |
| 192 | 204 | * @return ApiException |
| 193 | 205 | */ |
| 194 | - private static function create(string $basicMessage, int $rpcCode, $metadata, array $decodedMetadata, Exception $previous = null) | |
| 206 | + private static function create(string $basicMessage, int $rpcCode, $metadata, array $decodedMetadata, ?array $protobufErrors = null, ?Exception $previous = null) | |
| 195 | 207 | { |
| 196 | 208 | $containsErrorInfo = self::containsErrorInfo($decodedMetadata); |
| 197 | 209 | $rpcStatus = ApiStatus::statusFromRpcCode($rpcCode); |
| 198 | 210 | $messageData = ['message' => $basicMessage, 'code' => $rpcCode, 'status' => $rpcStatus, 'details' => $decodedMetadata]; |
| 199 | 211 | if ($containsErrorInfo) { |
| 200 | - $messageData = array_merge($containsErrorInfo, $messageData); | |
| 212 | + $messageData = \array_merge($containsErrorInfo, $messageData); | |
| 201 | 213 | } |
| 202 | - $message = json_encode($messageData, \JSON_PRETTY_PRINT); | |
| 214 | + $message = \json_encode($messageData, \JSON_PRETTY_PRINT); | |
| 203 | 215 | if ($metadata instanceof RepeatedField) { |
| 204 | - $metadata = iterator_to_array($metadata); | |
| 216 | + $metadata = \iterator_to_array($metadata); | |
| 205 | 217 | } |
| 206 | - return new ApiException($message, $rpcCode, $rpcStatus, ['previous' => $previous, 'metadata' => $metadata, 'basicMessage' => $basicMessage]); | |
| 218 | + return new ApiException($message, $rpcCode, $rpcStatus, ['previous' => $previous, 'metadata' => $metadata, 'basicMessage' => $basicMessage], $protobufErrors ?? []); | |
| 207 | 219 | } |
| 208 | 220 | /** |
| 221 | + * Encodes decoded metadata to the Protobuf error type | |
| 222 | + * | |
| 223 | + * @param array $metadata | |
| 224 | + * @return array | |
| 225 | + */ | |
| 226 | + private static function decodeMetadataToProtobufErrors(array $metadata) : array | |
| 227 | + { | |
| 228 | + $result = []; | |
| 229 | + Serializer::loadKnownMetadataTypes(); | |
| 230 | + foreach ($metadata as $error) { | |
| 231 | + $message = null; | |
| 232 | + if (!isset($error['@type'])) { | |
| 233 | + continue; | |
| 234 | + } | |
| 235 | + $type = $error['@type']; | |
| 236 | + if (!isset(KnownTypes::TYPE_URLS[$type])) { | |
| 237 | + continue; | |
| 238 | + } | |
| 239 | + $class = KnownTypes::TYPE_URLS[$type]; | |
| 240 | + $message = new $class(); | |
| 241 | + $jsonMessage = \json_encode(\array_diff_key($error, ['@type' => \true])); | |
| 242 | + $message->mergeFromJsonString($jsonMessage); | |
| 243 | + $result[] = $message; | |
| 244 | + } | |
| 245 | + return $result; | |
| 246 | + } | |
| 247 | + /** | |
| 209 | 248 | * @param Status $status |
| 210 | 249 | * @return ApiException |
| 211 | 250 | */ |
| 212 | 251 | public static function createFromRpcStatus(Status $status) |
| @@ -224,9 +263,9 @@ | ||
| 224 | 263 | public static function createFromRequestException(RequestException $ex, bool $isStream = \false) |
| 225 | 264 | { |
| 226 | 265 | $res = $ex->getResponse(); |
| 227 | 266 | $body = (string) $res->getBody(); |
| 228 | - $decoded = json_decode($body, \true); | |
| 267 | + $decoded = \json_decode($body, \true); | |
| 229 | 268 | // A streaming response body will return one error in an array. Parse |
| 230 | 269 | // that first (and only) error message, if provided. |
| 231 | 270 | if ($isStream && isset($decoded[0])) { |
| 232 | 271 | $decoded = $decoded[0]; |
| @@ -254,14 +293,6 @@ | ||
| 254 | 293 | */ |
| 255 | 294 | public function getMetadata() |
| 256 | 295 | { |
| 257 | 296 | return $this->metadata; |
| 258 | - } | |
| 259 | - /** | |
| 260 | - * String representation of ApiException | |
| 261 | - * @return string | |
| 262 | - */ | |
| 263 | - public function __toString() | |
| 264 | - { | |
| 265 | - return __CLASS__ . ": {$this->message}\n"; | |
| 266 | 297 | } |
| 267 | 298 | } |