Improve Sendcloud error handling

This commit is contained in:
Andreas Palm 2022-11-02 22:37:04 +01:00
parent 1c7e84d8f2
commit d676a1b09a
4 changed files with 122 additions and 61 deletions

View File

@ -28,16 +28,21 @@ class SendCloudApi
$this->private_key = $private_key; $this->private_key = $private_key;
} }
/**
* @throws SendcloudApiException
*/
public function GetSenderAddresses(): array public function GetSenderAddresses(): array
{ {
$uri = self::PROD_BASE_URI . '/user/addresses/sender'; $uri = self::PROD_BASE_URI . '/user/addresses/sender';
$response = $this->sendRequest($uri); $response = $this->sendRequest($uri);
$res = array(); foreach ($response['body']->sender_addresses as $item)
foreach ($response->sender_addresses as $item)
$res[] = SenderAddress::fromApiResponse($item); $res[] = SenderAddress::fromApiResponse($item);
return $res; return $res ?? [];
} }
/**
* @throws SendcloudApiException
*/
public function GetShippingProducts(string $sourceCountry, ?string $targetCountry = null, ?int $weight = null, public function GetShippingProducts(string $sourceCountry, ?string $targetCountry = null, ?int $weight = null,
?int $height = null, ?int $length = null, ?int $width = null): array ?int $height = null, ?int $length = null, ?int $width = null): array
{ {
@ -60,26 +65,36 @@ class SendCloudApi
$params['width_unit'] = 'centimeter'; $params['width_unit'] = 'centimeter';
} }
$response = $this->sendRequest($uri, $params); $response = $this->sendRequest($uri, $params);
return array_map(fn($x) => ShippingProduct::fromApiResponse($x), $response ?? []); return array_map(fn($x) => ShippingProduct::fromApiResponse($x), $response['body'] ?? []);
} }
/**
* @throws SendcloudApiException
*/
public function CreateParcel(ParcelCreation $parcel): ParcelResponse|string|null public function CreateParcel(ParcelCreation $parcel): ParcelResponse|string|null
{ {
$uri = self::PROD_BASE_URI . '/parcels'; $uri = self::PROD_BASE_URI . '/parcels';
$response = $this->sendRequest($uri, null, true, [ $response = $this->sendRequest($uri, null, true, ['parcel' => $parcel->toApiRequest()], [200,400]);
'parcel' => $parcel->toApiRequest() switch ($response['code']) {
]); case 200:
try {
if (isset($response->parcel)) if (isset($response->parcel))
try {
return ParcelResponse::fromApiResponse($response->parcel); return ParcelResponse::fromApiResponse($response->parcel);
} catch (Exception $e) {
throw new SendcloudApiException(previous: $e);
}
break;
case 400:
if (isset($response->error)) if (isset($response->error))
return $response->error->message; return $response->error->message;
} catch (Exception $e) { break;
return $e->getMessage();
} }
return null; throw SendcloudApiException::fromResponse($response);
} }
/**
* @throws SendcloudApiException
*/
public function DownloadDocument(Document $document): string public function DownloadDocument(Document $document): string
{ {
$curl = curl_init(); $curl = curl_init();
@ -90,10 +105,18 @@ class SendCloudApi
"Authorization: Basic " . base64_encode($this->public_key . ':' . $this->private_key) "Authorization: Basic " . base64_encode($this->public_key . ':' . $this->private_key)
], ],
]); ]);
return curl_exec($curl); $output = curl_exec($curl);
$code = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
if ($code != 200)
throw SendcloudApiException::fromResponse(['code' => $code, 'body' => $output]);
return $output;
} }
function sendRequest(string $uri, array $query_params = null, bool $post = false, array $postFields = null) /**
* @throws SendcloudApiException
*/
function sendRequest(string $uri, array $query_params = null, bool $post = false, array $postFields = null,
array $allowedResponseCodes = [200]): ?array
{ {
if (empty($this->public_key) || empty($this->private_key)) if (empty($this->public_key) || empty($this->private_key))
return null; return null;
@ -117,9 +140,18 @@ class SendCloudApi
]); ]);
} }
$output = curl_exec($curl); $output = json_decode(curl_exec($curl));
$code = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl); curl_close($curl);
return json_decode($output); $ret = [
'code' => $code,
'body' => $output,
];
if (!in_array($code, $allowedResponseCodes))
throw SendcloudApiException::fromResponse($ret);
return $ret;
} }
} }

View File

@ -0,0 +1,18 @@
<?php
namespace Xentral\Carrier\SendCloud;
use Exception;
class SendcloudApiException extends Exception
{
public static function fromResponse(array $response) : SendcloudApiException {
if (!isset($response['body']) || !is_object($response['body']))
return new SendcloudApiException();
return new SendcloudApiException(
$response['body']->error->message ?? '',
$response['body']->error->code ?? 0
);
}
}

View File

@ -8,6 +8,7 @@ use Xentral\Carrier\SendCloud\SendCloudApi;
use Xentral\Carrier\SendCloud\Data\SenderAddress; use Xentral\Carrier\SendCloud\Data\SenderAddress;
use Xentral\Carrier\SendCloud\Data\ShippingProduct; use Xentral\Carrier\SendCloud\Data\ShippingProduct;
use Xentral\Carrier\SendCloud\Data\ShippingMethod; use Xentral\Carrier\SendCloud\Data\ShippingMethod;
use Xentral\Carrier\SendCloud\SendcloudApiException;
require_once dirname(__DIR__) . '/class.versanddienstleister.php'; require_once dirname(__DIR__) . '/class.versanddienstleister.php';
@ -22,17 +23,13 @@ class Versandart_sendcloud extends Versanddienstleister
if (!isset($this->id)) if (!isset($this->id))
return; return;
$this->api = new SendCloudApi($this->settings->public_key, $this->settings->private_key); $this->api = new SendCloudApi($this->settings->public_key, $this->settings->private_key);
$this->options['customs_shipment_types'] = [
0 => 'Geschenk',
1 => 'Dokumente',
2 => 'Kommerzielle Waren',
3 => 'Erprobungswaren',
4 => 'Rücksendung'
];
} }
protected function FetchOptionsFromApi() protected function FetchOptionsFromApi()
{ {
if (isset($this->options))
return;
try {
$list = $this->api->GetSenderAddresses(); $list = $this->api->GetSenderAddresses();
foreach ($list as $item) { foreach ($list as $item) {
/* @var SenderAddress $item */ /* @var SenderAddress $item */
@ -44,12 +41,21 @@ class Versandart_sendcloud extends Versanddienstleister
/* @var ShippingProduct $item */ /* @var ShippingProduct $item */
$shippingProducts[$item->Code] = $item; $shippingProducts[$item->Code] = $item;
} }
} catch (SendcloudApiException $e) {
$this->app->Tpl->addMessage('error', $e->getMessage());
}
$this->options['senders'] = array_map(fn(SenderAddress $x) => strval($x), $senderAddresses ?? []); $this->options['senders'] = array_map(fn(SenderAddress $x) => strval($x), $senderAddresses ?? []);
$this->options['products'] = array_map(fn(ShippingProduct $x) => $x->Name, $shippingProducts ?? []); $this->options['products'] = array_map(fn(ShippingProduct $x) => $x->Name, $shippingProducts ?? []);
$this->options['products'][0] = ''; $this->options['products'][0] = '';
$this->options['selectedProduct'] = $shippingProducts[$this->settings->shipping_product] ?? []; $this->options['selectedProduct'] = $shippingProducts[$this->settings->shipping_product] ?? [];
natcasesort($this->options['products']); natcasesort($this->options['products']);
$this->options['customs_shipment_types'] = [
0 => 'Geschenk',
1 => 'Dokumente',
2 => 'Kommerzielle Waren',
3 => 'Erprobungswaren',
4 => 'Rücksendung'
];
} }
public function AdditionalSettings(): array public function AdditionalSettings(): array
@ -102,6 +108,7 @@ class Versandart_sendcloud extends Versanddienstleister
$parcel->ParcelItems[] = $item; $parcel->ParcelItems[] = $item;
} }
$parcel->Weight = floatval($json->weight) * 1000; $parcel->Weight = floatval($json->weight) * 1000;
try {
$result = $this->api->CreateParcel($parcel); $result = $this->api->CreateParcel($parcel);
if ($result instanceof ParcelResponse) { if ($result instanceof ParcelResponse) {
$sql = "INSERT INTO versand $sql = "INSERT INTO versand
@ -125,6 +132,9 @@ class Versandart_sendcloud extends Versanddienstleister
$response['messages'][] = ['class' => 'error', 'text' => $result]; $response['messages'][] = ['class' => 'error', 'text' => $result];
} }
echo json_encode($response); echo json_encode($response);
} catch (SendcloudApiException $e) {
$this->app->Tpl->addMessage('error', $e->getMessage());
}
$this->app->ExitXentral(); $this->app->ExitXentral();
} }
} }

View File

@ -209,6 +209,7 @@ class Versandarten {
WHERE `id` = $id LIMIT 1" WHERE `id` = $id LIMIT 1"
); );
$this->app->Tpl->Set('MESSAGE', '');
$this->app->Tpl->addMessage('success', "Die Daten wurden erfolgreich gespeichert!"); $this->app->Tpl->addMessage('success', "Die Daten wurden erfolgreich gespeichert!");
} }
} }