From 97b141332a0f0ff565c8a66f728e6436f05021d2 Mon Sep 17 00:00:00 2001 From: David Maus <maus@hab.de> Date: Thu, 30 May 2013 10:54:08 +0200 Subject: [PATCH] Refactor SOLR V4 ErrorListener * VuFind/Search/Solr/V4/ErrorListener.php (getResponseBodyMediaType): New function. Return normalized response body media type identifier. (analyzeJsonErrorResponse): New function. Analyze response body and return appropriate tags. (onSearchError): Refactored. Use new functions. --- .../VuFind/Search/Solr/V4/ErrorListener.php | 90 +++++++++++++++---- 1 file changed, 74 insertions(+), 16 deletions(-) diff --git a/module/VuFind/src/VuFind/Search/Solr/V4/ErrorListener.php b/module/VuFind/src/VuFind/Search/Solr/V4/ErrorListener.php index b66bab8cfab..74c018d0926 100644 --- a/module/VuFind/src/VuFind/Search/Solr/V4/ErrorListener.php +++ b/module/VuFind/src/VuFind/Search/Solr/V4/ErrorListener.php @@ -31,6 +31,7 @@ namespace VuFind\Search\Solr\V4; use VuFindSearch\Backend\Exception\HttpErrorException; +use Zend\Http\Response; use Zend\EventManager\EventInterface; /** @@ -44,6 +45,22 @@ use Zend\EventManager\EventInterface; */ class ErrorListener { + /** + * Parser error tag. + * + * @var string + */ + const TAG_PARSER_ERROR = 'VuFind\Search\ParserError'; + + /** + * Normalized media types. + * + * @var string + */ + const TYPE_OTHER = 'other'; + const TYPE_JSON = 'json'; + const TYPE_XML = 'xml'; + /** * Backends to listen on. * @@ -74,27 +91,68 @@ class ErrorListener { $backend = $event->getParam('backend'); if (in_array($backend, $this->backends)) { - $error = $event->getTarget(); + $error = $event->getTarget(); if ($error instanceOf HttpErrorException) { - $body = $error->getResponse()->getBody(); - $type = $error->getResponse()->getHeaders()->get('content-type') - ->toString(); - if (stristr($type, 'json')) { + $response = $error->getResponse(); + + $body = $response->getBody(); + $type = $this->getResponseBodyMediaType($response); + + if ($type === self::TYPE_JSON) { $body = json_decode($body); - $reason = isset($body->error->msg) ? $body->error->msg : ''; - } else if (stristr($type, 'xml')) { - // TODO -- parse XML response - $reason = ''; - } else { - $reason = ''; - } - if (stristr($reason, 'org.apache.solr.search.SyntaxError') - || stristr($reason, 'undefined field') - ) { - $error->addTag('VuFind\Search\ParserError'); + if (json_last_error() === \JSON_ERROR_NONE) { + $tags = $this->analyzeJsonErrorResponse($body); + foreach ($tags as $tag) { + $error->addTag($tag); + } + } } } } return $event; } + + /// Internal API + + /** + * Analyze JSON-encoded error response and return appropriate tags. + * + * @param StdLib $body Deserialize JSON body + * + * @return array Tags + */ + protected function analyzeJsonErrorResponse($body) + { + $tags = array(); + if (isset($body->error->msg)) { + $reason = $body->error->msg; + if (stristr($reason, 'org.apache.solr.search.SyntaxError') + || stristr($reason, 'undefined field')) { + $tags[] = self::TAG_PARSER_ERROR; + } + } + return $tags; + } + + /** + * Return normalized media type identifier. + * + * @param Response $response HTTP response + * + * @return string One of `json', `xml', or `other' + */ + protected function getResponseBodyMediaType(Response $response) + { + if ($response->getHeaders()->has('content-type')) { + $type = $response->getHeaders()->get('content-type')->getFieldValue(); + if (strpos($type, 'application/json') === 0) { + return self::TYPE_JSON; + } + if (strpos($type, 'application/xml') === 0) { + return self::TYPE_XML; + } + } + return self::TYPE_OTHER; + } + } \ No newline at end of file -- GitLab