<commit_before><?php

/*
 * This file is part of the RuudkPostmarkBundle package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Ruudk\PostmarkBundle\Postmark;

use Buzz\Browser;
use Buzz\Client\Curl;
use Buzz\Exception\ClientException;
use Ruudk\PostmarkBundle\Postmark\Exception\PostmarkException;

class Transport
{
    /**
     * @var \Buzz\Client\Curl
     */
    protected $curl;

    /**
     * Postmark API token
     *
     * @var string
     */
    protected $token;

    /**
     * @param string $token
     */
    public function __construct(Curl $curl, $token)
    {
        $this->curl = $curl;
        $this->token = $token;
    }

    /**
     * @param Message|array $input Array of messages or just one message
     * @return mixed
     */
    public function send($input)
    {
        if($input instanceof Message) {
            /**
             * @var \Ruudk\PostmarkBundle\Postmark\Message $input
             */
            return $this->post('email', $input->getPayload());
        }

        $data = array();
        foreach($input AS $message) {
            /**
             * @var \Ruudk\PostmarkBundle\Postmark\Message $message
             */
            $data[] = $message->getPayload();
        }

        if(count($data) === 1) {
            return $this->post('email', $data[0]);
        } elseif(count($data) > 500) {
            $results = array();
            $chunks = array_chunk($data, 500);
            foreach($chunks AS $chunk) {
                $results += $this->post('email/batch', $chunk);
            }
            return $results;
        } else {
            return $this->post('email/batch', $data);
        }
    }

    /**
     * @param string $path
     * @param array $data
     * @return mixed
     */
    protected function post($path, array $data)
    {
        try {
            $browser = new Browser($this->curl);

            /**
             * @var \Buzz\Message\Response $response
             */
            $response = $browser->post('https://api.postmarkapp.com/' . $path, array(
                'X-Postmark-Server-Token' => $this->token,
                'Content-Type'            => 'application/json',
                'Accept'                  => 'application/json'
            ), json_encode($data));

            $json = json_decode($response->getContent(), true);

            if($json['ErrorCode'] > 0) {
                if($json['ErrorCode'] !== 406) {
                    /**
                     * ErrorCode 406 means Inactive recipient, no need to throw an exception for that.
                     * For the rest, throw an exception.
                     */
                    throw new PostmarkException($json['Message'], $json['ErrorCode']);
                }
            }

            return $json;
        } catch(ClientException $exception) {
            throw new PostmarkException($exception->getMessage(), $exception->getCode(), $exception);
        } catch(\Exception $exception) {
            throw new PostmarkException($exception->getMessage(), $exception->getCode(), $exception);
        }
    }
}<commit_msg>Better error handling<commit_after><?php

/*
 * This file is part of the RuudkPostmarkBundle package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Ruudk\PostmarkBundle\Postmark;

use Buzz\Browser;
use Buzz\Client\Curl;
use Buzz\Exception\ClientException;
use Ruudk\PostmarkBundle\Postmark\Exception\PostmarkException;

class Transport
{
    /**
     * @var \Buzz\Client\Curl
     */
    protected $curl;

    /**
     * Postmark API token
     *
     * @var string
     */
    protected $token;

    /**
     * @param string $token
     */
    public function __construct(Curl $curl, $token)
    {
        $this->curl = $curl;
        $this->token = $token;
    }

    /**
     * @param Message|array $input Array of messages or just one message
     * @return mixed
     */
    public function send($input)
    {
        if($input instanceof Message) {
            /**
             * @var \Ruudk\PostmarkBundle\Postmark\Message $input
             */
            return $this->post('email', $input->getPayload());
        }

        $data = array();
        foreach($input AS $message) {
            /**
             * @var \Ruudk\PostmarkBundle\Postmark\Message $message
             */
            $data[] = $message->getPayload();
        }

        if(count($data) === 1) {
            return $this->post('email', $data[0]);
        } elseif(count($data) > 500) {
            $results = array();
            $chunks = array_chunk($data, 500);
            foreach($chunks AS $chunk) {
                $results += $this->post('email/batch', $chunk);
            }
            return $results;
        } else {
            return $this->post('email/batch', $data);
        }
    }

    /**
     * @param string $path
     * @param array $data
     * @return mixed
     */
    protected function post($path, array $data)
    {
        try {
            $browser = new Browser($this->curl);

            /**
             * @var \Buzz\Message\Response $response
             */
            $response = $browser->post('https://api.postmarkapp.com/' . $path, array(
                'X-Postmark-Server-Token' => $this->token,
                'Content-Type'            => 'application/json',
                'Accept'                  => 'application/json'
            ), json_encode($data));

            if($response->getStatusCode() === 401) {
                throw new PostmarkException('Unauthorized: Missing or incorrect API Key header', 401);
            }

            if($response->getStatusCode() === 500) {
                throw new PostmarkException('Internal Server Error: The Postmark API returned a 500 error', 500);
            }

            if($response->getStatusCode() === 200 || $response->getStatusCode() === 422) {
                $json = json_decode($response->getContent(), true);

                if(isset($json['ErrorCode']) && $json['ErrorCode'] > 0) {
                    if($json['ErrorCode'] !== 406) {
                        /**
                         * ErrorCode 406 means Inactive recipient, no need to throw an exception for that.
                         * For the rest, throw an exception.
                         */
                        throw new PostmarkException($json['Message'], $json['ErrorCode']);
                    }
                }

                return $json;
            }
        } catch(PostmarkException $exception) {
            throw $exception;
        } catch(ClientException $exception) {
            throw new PostmarkException($exception->getMessage(), $exception->getCode(), $exception);
        } catch(\Exception $exception) {
            throw new PostmarkException($exception->getMessage(), $exception->getCode(), $exception);
        }
    }
}
{'fraction_non_alphanumeric': 0.1372965322009908, 'fraction_numerical': 0.007218683651804671, 'mean_word_length': 1.675501703900038, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 55, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1166100', 'n_tokens_mistral': 1962, 'n_tokens_neox': 1854, 'n_words': 440}