From c8ea3f869ee93ac31fbe4b244500800bad26e9bc Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Fri, 4 Sep 2020 12:07:53 +0300 Subject: [PATCH] error handling body --- application/Espo/Core/Api/ErrorOutput.php | 22 +++++++-- .../Espo/Core/Exceptions/BodyTrait.php | 49 +++++++++++++++++++ application/Espo/Core/Exceptions/Conflict.php | 6 ++- application/Espo/Core/Exceptions/Error.php | 2 +- application/Espo/Services/Record.php | 33 ++++++++----- 5 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 application/Espo/Core/Exceptions/BodyTrait.php diff --git a/application/Espo/Core/Api/ErrorOutput.php b/application/Espo/Core/Api/ErrorOutput.php index 8382c0c993..fd123c0677 100644 --- a/application/Espo/Core/Api/ErrorOutput.php +++ b/application/Espo/Core/Api/ErrorOutput.php @@ -68,7 +68,7 @@ class ErrorOutput public function process( Response $response, Throwable $exception, - bool $toPrint = false, + bool $toPrintBody = false, ?array $route = null, ?array $routeParams = null ) { @@ -135,7 +135,7 @@ class ErrorOutput $GLOBALS['log']->log($logLevel, $logMessage); - $toPrintXStatusReason = true; + $toPrintBodyXStatusReason = true; if ( $exception && @@ -143,7 +143,7 @@ class ErrorOutput get_class($exception), $this->ignorePrintXStatusReasonExceptionClassNameList ) ) { - $toPrintXStatusReason = false; + $toPrintBodyXStatusReason = false; } if (!in_array($statusCode, $this->allowedStatusCodeList)) { @@ -152,12 +152,24 @@ class ErrorOutput $response->setStatus($statusCode); - if ($toPrintXStatusReason) { + if ($toPrintBodyXStatusReason) { $response->setHeader('X-Status-Reason', $this->stripInvalidCharactersFromHeaderValue($message)); } - if ($toPrint) { + $exceptionBody = null; + if (method_exists($exception, 'getBody')) { + $exceptionBody = $exception->getBody(); + } + + if ($exceptionBody) { + $response->writeBody($exceptionBody); + + $toPrintBody = false; + } + + if ($toPrintBody) { $statusText = $this->getCodeDescription($statusCode); + $statusText = isset($statusText) ? $statusCode . ' '. $statusText : 'HTTP ' . $statusCode; diff --git a/application/Espo/Core/Exceptions/BodyTrait.php b/application/Espo/Core/Exceptions/BodyTrait.php new file mode 100644 index 0000000000..4861b28b16 --- /dev/null +++ b/application/Espo/Core/Exceptions/BodyTrait.php @@ -0,0 +1,49 @@ +body = $body; + + return $exception; + } + + public function getBody() : ?string + { + return $this->body; + } +} diff --git a/application/Espo/Core/Exceptions/Conflict.php b/application/Espo/Core/Exceptions/Conflict.php index 39957a5570..31c6e91f61 100644 --- a/application/Espo/Core/Exceptions/Conflict.php +++ b/application/Espo/Core/Exceptions/Conflict.php @@ -29,7 +29,11 @@ namespace Espo\Core\Exceptions; -class Conflict extends \Exception +use Exception; + +class Conflict extends Exception { + use BodyTrait; + protected $code = 409; } diff --git a/application/Espo/Core/Exceptions/Error.php b/application/Espo/Core/Exceptions/Error.php index f537652e54..62943d823f 100644 --- a/application/Espo/Core/Exceptions/Error.php +++ b/application/Espo/Core/Exceptions/Error.php @@ -31,5 +31,5 @@ namespace Espo\Core\Exceptions; class Error extends InternalServerError { - + use BodyTrait; } diff --git a/application/Espo/Services/Record.php b/application/Espo/Services/Record.php index 415324a308..7da5c2f021 100644 --- a/application/Espo/Services/Record.php +++ b/application/Espo/Services/Record.php @@ -932,20 +932,27 @@ class Record implements Crud, protected function processDuplicateCheck(Entity $entity, $data) { - if (empty($data->_skipDuplicateCheck) && empty($data->skipDuplicateCheck) && empty($data->forceDuplicate)) { - $duplicateList = $this->findDuplicates($entity, $data); - if (!empty($duplicateList)) { - $data = []; - foreach ($duplicateList as $e) { - $data[$e->id] = $e->getValueMap(); - } - $reason = [ - 'reason' => 'Duplicate', - 'data' => $data - ]; - throw new ConflictSilent(json_encode($reason)); - } + if ( + !empty($data->_skipDuplicateCheck) || + !empty($data->skipDuplicateCheck) || + !empty($data->forceDuplicate) + ) { + return; } + + $duplicateList = $this->findDuplicates($entity, $data); + + if (empty($duplicateList)) { + return; + } + + $list = []; + + foreach ($duplicateList as $e) { + $list[] = $e->getValueMap(); + } + + throw ConflictSilent::createWithBody('duplicate', json_encode($list)); } public function populateDefaults(Entity $entity, $data)