diff --git a/src/PureMachine/Bundle/SDKBundle/Exception/Exception.php b/src/PureMachine/Bundle/SDKBundle/Exception/Exception.php index bed20fa..70933ff 100644 --- a/src/PureMachine/Bundle/SDKBundle/Exception/Exception.php +++ b/src/PureMachine/Bundle/SDKBundle/Exception/Exception.php @@ -5,13 +5,24 @@ class Exception extends \Exception { + + /** + * @var ExceptionStore + */ private $exceptionStore; const DEFAULT_ERROR_CODE = 'GENERIC_001'; - const GENERIC_001 = 'GENERIC_001'; const GENERIC_001_MESSAGE = 'Unknown error'; + /** + * Exception constructor. + * + * @param string $detailedMessage + * @param null $code + * @param \Exception|null $previous + * @param ExceptionStore|null $exceptionStore + */ public function __construct($detailedMessage = "", $code = null, \Exception $previous = null, ExceptionStore $exceptionStore=null) { @@ -28,6 +39,16 @@ public function __construct($detailedMessage = "", $code = null, \Exception $pre $this->setup($code, $message, null, $detailedMessage, $exceptionStore); } + /** + * Setups a new internal exception store on the exception class + * This exception store is built from the arguments of this method call + * + * @param $code + * @param $message + * @param $merchantMessage + * @param $debugMessage + * @param ExceptionStore|null $exceptionStore + */ protected function setup($code, $message, $merchantMessage, $debugMessage, ExceptionStore $exceptionStore=null) { @@ -36,9 +57,9 @@ protected function setup($code, $message, $merchantMessage, $debugMessage, } else { $this->exceptionStore = new ExceptionStore(); - $this->exceptionStore->setMessage($message); + $this->exceptionStore->setErrorMessage($message); $this->exceptionStore->setDetailledMessage($debugMessage); - $this->exceptionStore->setCode($code); + $this->exceptionStore->setErrorCode($code); $this->exceptionStore->setExceptionClass(get_class($this)); $t = explode('\n', $this->getTraceAsString()); $this->exceptionStore->setStack($t); @@ -77,24 +98,95 @@ protected static function searchForFileAndLineCalledFromStack(array $stack) return null; } + /** + * Build a exceptionStore from a PHP Exception + * @param \Exception $e + * @return ExceptionStore + */ + public static function buildExceptionStore(\Exception $e) + { + $exceptionStore = new ExceptionStore(); + $exceptionStore->setErrorMessage($e->getMessage()); + $exceptionStore->setErrorCode($e->getCode()); + $exceptionStore->setExceptionClass(get_class($e)); + $t = explode('\n', $e->getTraceAsString()); + $exceptionStore->setStack($t); + + $stack = $e->getTrace(); + if (count($stack) > 0) { + //Setting default unknown values + $exceptionStore->setFile("unknown"); + $exceptionStore->setLine(0); + //Searching for a valid stackItem + $stackItem = static::searchForFileAndLineCalledFromStack($stack); + if (!is_null($stackItem)) { + $exceptionStore->setFile(basename($stackItem['file'],'.php')); + $exceptionStore->setLine($stackItem['line']); + } + } + + return $exceptionStore; + } + + /* + * Getters and setters + */ + + /** + * Returns the exception store + * + * @return ExceptionStore + */ public function getStore() { return $this->exceptionStore; } - public function setStore($e) + /** + * Injects the exception store on the exception + * instance + * + * @param ExceptionStore $e + * @return Exception + */ + public function setStore(ExceptionStore $e) { - return $this->exceptionStore = $e; + $this->exceptionStore = $e; + return $this; } - public function addMessage($key, $value) + /** + * Sets the message on the internal exception store + * + * @param $value + */ + public function setErrorMessage($value) { - $this->exceptionStore->addMessage($key, $value); + $this->exceptionStore->setErrorMessage($value); } + /** + * Returns the errorCode on the internal exception store + * + * @return string + */ public function getErrorCode() { - return $this->exceptionStore->getCode(); + return $this->exceptionStore->getErrorCode(); + } + + /** + * Concat the sent element message on the errorMessage + * string. + * + * @param $message + */ + public function addErrorMessage($message) + { + if (!$this->exceptionStore->getErrorMessage()) { + $this->exceptionStore->setErrorMessage(''); + } + return $this->exceptionStore->setErrorMessage($this->exceptionStore->getErrorMessage().', ' . $message); } public function setMerchantDetails($merchantMessage) @@ -129,31 +221,46 @@ public function setMetadata($value) } /** - * Build a exceptionStore from a PHP Exception - * @param \Exception $e + * Returns the detailed error message from the internal exception store + * + * @return mixed */ - public static function buildExceptionStore(\Exception $e) + public function getDetailedErrorMessage() { - $exceptionStore = new ExceptionStore(); - $exceptionStore->setMessage($e->getMessage()); - $exceptionStore->setCode($e->getCode()); - $exceptionStore->setExceptionClass(get_class($e)); - $t = explode('\n', $e->getTraceAsString()); - $exceptionStore->setStack($t); + return $this->exceptionStore->getDetailedErrorMessage(); + } - $stack = $e->getTrace(); - if (count($stack) > 0) { - //Setting default unknown values - $exceptionStore->setFile("unknown"); - $exceptionStore->setLine(0); - //Searching for a valid stackItem - $stackItem = static::searchForFileAndLineCalledFromStack($stack); - if (!is_null($stackItem)) { - $exceptionStore->setFile(basename($stackItem['file'],'.php')); - $exceptionStore->setLine($stackItem['line']); - } - } + /** + * Returns the detailed error code from the internal exception store + * + * @return mixed + */ + public function getDetailedErrorCode() + { + return $this->exceptionStore->getDetailedErrorCode(); + } - return $exceptionStore; + /** + * Sets the detailed error message of the internal exception store + * + * @param $value + * @return Exception + */ + public function setDetailedErrorMessage($value) + { + $this->exceptionStore->setDetailedErrorMessage($value); + return $this; + } + + /** + * Sets the detailed error code of the internal exception store + * + * @param $value + * @return Exception + */ + public function setDetailedErrorCode($value) + { + $this->exceptionStore->setDetailedErrorCode($value); + return $this; } } diff --git a/src/PureMachine/Bundle/SDKBundle/Exception/ExceptionElementInterface.php b/src/PureMachine/Bundle/SDKBundle/Exception/ExceptionElementInterface.php new file mode 100644 index 0000000..856ff74 --- /dev/null +++ b/src/PureMachine/Bundle/SDKBundle/Exception/ExceptionElementInterface.php @@ -0,0 +1,27 @@ +getAnswer()->getCode() .": ". $answer->getAnswer()->getMessage() ." \n"; + $message = $answer->getAnswer()->getErrorCode() .": ". $answer->getAnswer()->getErrorMessage() ." \n"; if ($answer->getAnswer()->isStoreProperty('detailledMessage')) { $message .= $answer->getAnswer()->getDetailledMessage(); @@ -95,7 +95,7 @@ public static function raiseIfError($answer, $displayStack=false) if (class_exists($class)) { $ex = null; try { - $ex = new $class($message, $answer->getAnswer()->getCode(), null); + $ex = new $class($message, $answer->getAnswer()->getErrorCode(), null); if ($ex instanceof Exception) { $ex->setStore($answer->getAnswer()); } @@ -109,8 +109,8 @@ public static function raiseIfError($answer, $displayStack=false) } $e = new WebServiceException($message); - $e->getStore()->setMessage($answer->getAnswer()->getMessage()); - $e->getStore()->setCode($answer->getAnswer()->getCode()); + $e->getStore()->setErrorMessage($answer->getAnswer()->getErrorMessage()); + $e->getStore()->setErrorCode($answer->getAnswer()->getErrorCode()); throw $e; } } diff --git a/src/PureMachine/Bundle/SDKBundle/Service/HttpHelper.php b/src/PureMachine/Bundle/SDKBundle/Service/HttpHelper.php index 3ddd46e..e47a9dc 100644 --- a/src/PureMachine/Bundle/SDKBundle/Service/HttpHelper.php +++ b/src/PureMachine/Bundle/SDKBundle/Service/HttpHelper.php @@ -242,9 +242,9 @@ public function httpRequest($url, $data=null, $method='POST', $e = $this->createException($message, $exception_code); - $e->addMessage('output', $output); - $e->addMessage('called URL', $url); - $e->addMessage('data sent:', $data); + $e->addErrorMessage('output', $output); + $e->addErrorMessage('called URL', $url); + $e->addErrorMessage('data sent:', $data); $this->triggerHttpRequestEvent($data, $output, $url, $method, $statusCode, $duration); throw $e; } @@ -253,9 +253,9 @@ public function httpRequest($url, $data=null, $method='POST', $e = $this->createException("HTTP exception: error " . $statusCode ." for ". $url ." . Page or service not found.", HTTPException::HTTP_404); - $e->addMessage('output', $output); - $e->addMessage('called URL', $url); - $e->addMessage('data sent:', $data); + $e->addErrorMessage('output', $output); + $e->addErrorMessage('called URL', $url); + $e->addErrorMessage('data sent:', $data); $this->triggerHttpRequestEvent($data, $output, $url, $method, $statusCode, $duration); throw $e; } @@ -264,9 +264,9 @@ public function httpRequest($url, $data=null, $method='POST', $e = $this->createException("HTTP exception: error " . $statusCode ." for ". $url ." . Invalid credentials.", HTTPException::HTTP_401); - $e->addMessage('output', $output); - $e->addMessage('called URL', $url); - $e->addMessage('data sent:', $data); + $e->addErrorMessage('output', $output); + $e->addErrorMessage('called URL', $url); + $e->addErrorMessage('data sent:', $data); $this->triggerHttpRequestEvent($data, $output, $url, $method, $statusCode, $duration); throw $e; } @@ -274,9 +274,9 @@ public function httpRequest($url, $data=null, $method='POST', if ($this->proxy && $statusCode == 100) { $errorMessage = "HTTP Timeout (100)for " . $url; $e = $this->createException($errorMessage, HTTPException::HTTP_100); - $e->addMessage('output', $output); - $e->addMessage('called URL', $url); - $e->addMessage('data sent:', $data); + $e->addErrorMessage('output', $output); + $e->addErrorMessage('called URL', $url); + $e->addErrorMessage('data sent:', $data); $this->triggerHttpRequestEvent($data, $output, $url, $method, $statusCode, $duration); throw $e; } @@ -284,9 +284,9 @@ public function httpRequest($url, $data=null, $method='POST', if ($statusCode != 200) { $errorMessage = "HTTP exception: error " . $statusCode . " for $url"; $e = $this->createException($errorMessage, HTTPException::HTTP_500); - $e->addMessage('output', $output); - $e->addMessage('called URL', $url); - $e->addMessage('data sent:', $data); + $e->addErrorMessage('output', $output); + $e->addErrorMessage('called URL', $url); + $e->addErrorMessage('data sent:', $data); $this->triggerHttpRequestEvent($data, $output, $url, $method, $statusCode, $duration); throw $e; } diff --git a/src/PureMachine/Bundle/SDKBundle/Service/WebServiceClient.php b/src/PureMachine/Bundle/SDKBundle/Service/WebServiceClient.php index ca6d667..8e0eb57 100644 --- a/src/PureMachine/Bundle/SDKBundle/Service/WebServiceClient.php +++ b/src/PureMachine/Bundle/SDKBundle/Service/WebServiceClient.php @@ -18,6 +18,7 @@ use PureMachine\Bundle\SDKBundle\Store\WebService\DebugErrorResponse; use PureMachine\Bundle\SDKBundle\Store\Base\StoreHelper; use Symfony\Component\Validator\Validation; +use PureMachine\Bundle\SDKBundle\Exception\ExceptionElementInterface; /** * Needed because there is an annotation Inheritance bug in PHP 5.3.3 (centOS version) @@ -424,7 +425,7 @@ public function buildErrorResponse($webServiceName, $version, \Exception $except //Translate the exception if possible if($this->isSymfony() && $this->symfonyContainer) { $translatedMessage = $this->translateException($data); - if(!is_null($translatedMessage)) $data->setMessage($translatedMessage); + if(!is_null($translatedMessage)) $data->setErrorMessage($translatedMessage); } if ($serialize) $data = $data->serialize(); @@ -458,8 +459,15 @@ protected function translateException($store) if(!$this->isSymfony() || !$this->symfonyContainer) return null; $translator = $this->getSymfonyTranslator(); - $translatedMessage = $translator->trans($store->getCode(), array(), 'messages', $translator->getLocale()); - if($translatedMessage!=$store->getCode()) return $translatedMessage; + $errorCode = null; + if ($store instanceof ExceptionElementInterface) { + $errorCode = $store->getErrorCode(); + } else { + $errorCode = $store->getCode(); + } + + $translatedMessage = $translator->trans($errorCode, array(), 'messages', $translator->getLocale()); + if($translatedMessage!=$errorCode) return $translatedMessage; return null; } diff --git a/src/PureMachine/Bundle/SDKBundle/Store/ExceptionStore.php b/src/PureMachine/Bundle/SDKBundle/Store/ExceptionStore.php index 9c39493..099305e 100644 --- a/src/PureMachine/Bundle/SDKBundle/Store/ExceptionStore.php +++ b/src/PureMachine/Bundle/SDKBundle/Store/ExceptionStore.php @@ -3,32 +3,53 @@ use Symfony\Component\Validator\Constraints as Assert; use PureMachine\Bundle\SDKBundle\Store\Annotation as Store; +use PureMachine\Bundle\SDKBundle\Exception\ExceptionElementInterface; /** * Class ExceptionStore * @package PureMachine\Bundle\SDKBundle\Store * - * @method getMessage() - * @method getCode() + * @method getErrorMessage() + * @method getErrorCode() + * @method getDetailedErrorMessage() + * @method getDetailedErrorCode() * @method getExceptionClass() * @method getTicket() * @method getDetailledMessage() + * @method setErrorMessage() + * @method setErrorCode() + * @method setDetailedErrorMessage() + * @method setDetailedErrorCode() */ -class ExceptionStore extends Base\BaseStore +class ExceptionStore extends Base\BaseStore implements ExceptionElementInterface { /** * @Store\Property(description="Exception generic message") * @Assert\Type("string") * @Assert\NotBlank */ - protected $message; + protected $errorMessage; /** * @Store\Property(description="Exception error code.") * @Assert\Type("string") * @Assert\NotBlank */ - protected $code; + protected $errorCode; + + /** + * @Store\Property(description="Raw exception generic message") + * @Assert\Type("string") + * @Assert\NotBlank + */ + protected $detailedErrorMessage; + + /** + * @Store\Property(description="Raw exception error code.") + * @Assert\Type("string") + * @Assert\NotBlank + */ + protected $detailedErrorCode; /** * @Store\Property(description="Full exception class name.") @@ -97,7 +118,7 @@ public function getDetailedMessage() public function getCompleteMessage() { - return $this->getMessage(). ": " . $this->getDetailledMessage() + return $this->getErrorMessage(). ": " . $this->getDetailledMessage() ." in " . $this->getFile() .":" . $this->getLine(); } @@ -108,4 +129,22 @@ public function addMetadata($key, $value) return $this; } + /*** + * FIXME: For retrocompatibility, to remove + * @return mixed + */ + public function getMessage() + { + return $this->errorMessage; + } + + /*** + * FIXME: For retrocompatibility, to remove + * @return mixed + */ + public function getCode() + { + return $this->errorCode; + } + } diff --git a/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php b/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php index 44a513a..7edd078 100644 --- a/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php +++ b/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php @@ -4,10 +4,12 @@ use PureMachine\Bundle\SDKBundle\Exception\Exception; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use PureMachine\Bundle\StoreBundle\Store\Base\BaseStoreInterface; +use PureMachine\Bundle\SDKBundle\Exception\ExceptionElementInterface; /** * @code - * ./bin/phpunit -v -c app vendor/puremachine/sdk/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php + * ./bin/phpunit -v -c app vendor/puremachine/sdk/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php * @endcode */ class ExceptionTest extends WebTestCase @@ -15,7 +17,7 @@ class ExceptionTest extends WebTestCase /** * @code - * phpunit -v --filter testMetadataGetterSetterAdder -c app vendor/puremachine/sdk/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php + * ./bin/phpunit -v --filter testMetadataGetterSetterAdder -c app vendor/puremachine/sdk/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php * @endcode */ public function testMetadataGetterSetterAdder() @@ -40,4 +42,21 @@ public function testMetadataGetterSetterAdder() $this->assertEquals('value3', $tmpValues['key2']); } + /** + * @code + * ./bin/phpunit -v --filter testCreateExceptionStoreFromException -c app vendor/puremachine/sdk/src/PureMachine/Bundle/SDKBundle/Tests/ExceptionTest.php + * @endcode + */ + public function testCreateExceptionStoreFromException() + { + $exception = new Exception(); + + $store = $exception->buildExceptionStore(new \Exception("sample simple exception", -1101)); + + $this->assertEquals('sample simple exception', $store->getErrorMessage()); + $this->assertEquals(-1101, $store->getErrorCode()); + $this->assertTrue($store instanceof BaseStoreInterface); + $this->assertTrue($store instanceof ExceptionElementInterface); + } + }