Skip to content

Commit

Permalink
Merge pull request #7 from zf-fr/better-error
Browse files Browse the repository at this point in the history
Better error
  • Loading branch information
bakura10 committed Apr 10, 2014
2 parents 22f4b20 + 1855c5c commit 8f444cf
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 15 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 1.6.0

* Add new useful and more precise exceptions. This may be a minor BC. Before this release, ZfrStripe used to throw
a CardErrorException on 402. Now, it only throws this exception if the error type is `card_error`, otherwise it
throws a RequestFailedException. Alternatively, the ValidationErrorException has been replaced with a more generic
BadRequestException, which more closely follows Stripe API. Furthermore, an ApiRateLimitException has been added to
easily track an API rate limit error.

# 1.5.3

* Add missing `subscription` parameter to `getUpcomingInvoice` method since 2014-01-31
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,12 @@ ZfrStripe tries its best to throw useful exceptions. Two kinds of exceptions can
Here are all the exceptions:

* `ZfrStripe\Exception\UnauthorizedException`: your API key is likely to be wrong...
* `ZfrStripe\Exception\CardErrorException`: occurs for 402 errors. According to Stripe, this error happen when
* `ZfrStripe\Exception\ApiRateLimitException`: occurs when you have reached the Stripe API limit.
* `ZfrStripe\Exception\BadRequestException`: occurs for 400 error code.
* `ZfrStripe\Exception\CardErrorException`: occurs for any card errors. According to Stripe, this error happen when
parameters were valid but the request failed (for instance if a card CVC is invalid).
* `ZfrStripe\Exception\NotFoundException`: is thrown whenever client receives a 404 exception.
* `ZfrStripe\Exception\ValidationErrorException`: some errors on your sent data.
* `ZfrStripe\Exception\RequestFailedException`: occurs for generic 402 error.
* `ZfrStripe\Exception\ServerErrorException`: any errors where Stripe is likely to be doing something wrong...

Usage:
Expand Down
4 changes: 2 additions & 2 deletions src/ZfrStripe/Client/ServiceDescription/Stripe-2013-12-03.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

$errors = array(
array(
'class' => 'ZfrStripe\Exception\ValidationErrorException',
'class' => 'ZfrStripe\Exception\BadRequestException',
'code' => 400
),
array(
'class' => 'ZfrStripe\Exception\UnauthorizedException',
'code' => 401
),
array(
'class' => 'ZfrStripe\Exception\CardErrorException',
'class' => 'ZfrStripe\Exception\RequestFailedException',
'code' => 402
),
array(
Expand Down
4 changes: 2 additions & 2 deletions src/ZfrStripe/Client/ServiceDescription/Stripe-2014-01-31.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

$errors = array(
array(
'class' => 'ZfrStripe\Exception\ValidationErrorException',
'class' => 'ZfrStripe\Exception\BadRequestException',
'code' => 400
),
array(
'class' => 'ZfrStripe\Exception\UnauthorizedException',
'code' => 401
),
array(
'class' => 'ZfrStripe\Exception\CardErrorException',
'class' => 'ZfrStripe\Exception\RequestFailedException',
'code' => 402
),
array(
Expand Down
4 changes: 2 additions & 2 deletions src/ZfrStripe/Client/ServiceDescription/Stripe-2014-03-13.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

$errors = array(
array(
'class' => 'ZfrStripe\Exception\ValidationErrorException',
'class' => 'ZfrStripe\Exception\BadRequestException',
'code' => 400
),
array(
'class' => 'ZfrStripe\Exception\UnauthorizedException',
'code' => 401
),
array(
'class' => 'ZfrStripe\Exception\CardErrorException',
'class' => 'ZfrStripe\Exception\RequestFailedException',
'code' => 402
),
array(
Expand Down
4 changes: 2 additions & 2 deletions src/ZfrStripe/Client/ServiceDescription/Stripe-2014-03-28.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

$errors = array(
array(
'class' => 'ZfrStripe\Exception\ValidationErrorException',
'class' => 'ZfrStripe\Exception\BadRequestException',
'code' => 400
),
array(
'class' => 'ZfrStripe\Exception\UnauthorizedException',
'code' => 401
),
array(
'class' => 'ZfrStripe\Exception\CardErrorException',
'class' => 'ZfrStripe\Exception\RequestFailedException',
'code' => 402
),
array(
Expand Down
16 changes: 13 additions & 3 deletions src/ZfrStripe/Exception/AbstractException.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,20 @@ abstract class AbstractException extends \Exception implements ExceptionInterfac
*/
public static function fromCommand(CommandInterface $command, Response $response)
{
$errors = json_decode($response->getBody(true), true);
$error = isset($errors['error']['message']) ? $errors['error']['message'] : 'Unknown error';
$errors = json_decode($response->getBody(true), true);
$type = $errors['error']['type'];
$message = isset($errors['error']['message']) ? $errors['error']['message'] : 'Unknown error';
$code = isset($errors['error']['code']) ? $errors['error']['code'] : null;

// We can trigger very specific exception based on the type and code
if ($type === 'card_error') {
$exception = new CardErrorException($message, $response->getStatusCode());
} elseif ($type === 'invalid_request_error' && $code === 'rate_limit') {
$exception = new ApiRateLimitException($message, $response->getStatusCode());
} else {
$exception = new static($message, $response->getStatusCode());
}

$exception = new static($error, $response->getStatusCode());
$exception->setRequest($command->getRequest());
$exception->setResponse($response);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
* @author Michaël Gallego <[email protected]>
* @licence MIT
*/
class ValidationErrorException extends AbstractException
class ApiRateLimitException extends BadRequestException
{
}
27 changes: 27 additions & 0 deletions src/ZfrStripe/Exception/BadRequestException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrStripe\Exception;

/**
* @author Michaël Gallego <[email protected]>
* @licence MIT
*/
class BadRequestException extends AbstractException
{
}
2 changes: 1 addition & 1 deletion src/ZfrStripe/Exception/CardErrorException.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
* @author Michaël Gallego <[email protected]>
* @licence MIT
*/
class CardErrorException extends AbstractException
class CardErrorException extends RequestFailedException
{
}
27 changes: 27 additions & 0 deletions src/ZfrStripe/Exception/RequestFailedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrStripe\Exception;

/**
* @author Michaël Gallego <[email protected]>
* @licence MIT
*/
class RequestFailedException extends AbstractException
{
}
72 changes: 72 additions & 0 deletions tests/ZfrStripeTest/Exception/ExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrStripeTest\Exception;

use Guzzle\Http\Message\Response;
use ZfrStripe\Exception\BadRequestException;
use ZfrStripe\Exception\RequestFailedException;

/**
* @author Michaël Gallego <[email protected]>
* @licence MIT
*/
class ExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testCanCreateException()
{
$command = $this->getMock('Guzzle\Service\Command\CommandInterface');
$request = $this->getMock('Guzzle\Http\Message\Request', [], [], '', false);
$command->expects($this->once())->method('getRequest')->will($this->returnValue($request));
$response = new Response(400);
$response->setBody('');

$exception = BadRequestException::fromCommand($command, $response);

$this->assertInstanceOf('ZfrStripe\Exception\BadRequestException', $exception);
}

public function testCanCreateCardErrorException()
{
$command = $this->getMock('Guzzle\Service\Command\CommandInterface');
$request = $this->getMock('Guzzle\Http\Message\Request', [], [], '', false);
$command->expects($this->once())->method('getRequest')->will($this->returnValue($request));
$response = new Response(402);
$response->setBody(json_encode(array('error' => array('type' => 'card_error'))));

$exception = RequestFailedException::fromCommand($command, $response);

$this->assertInstanceOf('ZfrStripe\Exception\CardErrorException', $exception);
}

public function testCanCreateApiRateLimitErrorException()
{
$command = $this->getMock('Guzzle\Service\Command\CommandInterface');
$request = $this->getMock('Guzzle\Http\Message\Request', [], [], '', false);
$command->expects($this->once())->method('getRequest')->will($this->returnValue($request));
$response = new Response(400);
$response->setBody(json_encode(array('error' => array(
'type' => 'invalid_request_error',
'code' => 'rate_limit'
))));

$exception = BadRequestException::fromCommand($command, $response);

$this->assertInstanceOf('ZfrStripe\Exception\ApiRateLimitException', $exception);
}
}

0 comments on commit 8f444cf

Please sign in to comment.