From 35078669abfbe296b578b3f131a30dcb38ed99f5 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 7 Mar 2019 13:29:48 +0100 Subject: [locationinfo] Add error log for backends --- .../locationinfo/inc/coursebackend.inc.php | 32 +++++++--- .../coursebackend/coursebackend_davinci.inc.php | 36 +++++------ .../inc/coursebackend/coursebackend_dummy.inc.php | 12 ++-- .../coursebackend/coursebackend_exchange.inc.php | 12 ++-- .../coursebackend/coursebackend_hisinone.inc.php | 70 +++++++++------------- .../locationinfo/inc/locationinfo.inc.php | 17 +++++- 6 files changed, 95 insertions(+), 84 deletions(-) (limited to 'modules-available/locationinfo/inc') diff --git a/modules-available/locationinfo/inc/coursebackend.inc.php b/modules-available/locationinfo/inc/coursebackend.inc.php index 68a0e09b..bc5b059e 100644 --- a/modules-available/locationinfo/inc/coursebackend.inc.php +++ b/modules-available/locationinfo/inc/coursebackend.inc.php @@ -15,9 +15,13 @@ abstract class CourseBackend */ private static $backendTypes = false; /** - * @var boolean|string false = no error, error message otherwise + * @var boolean|string legacy, do not use */ - protected $error; + protected $error = false; + /** + * @var array list of errors that occured, fill using addError() + */ + private $errors; /** * @var int as internal serverId */ @@ -32,7 +36,12 @@ abstract class CourseBackend */ public final function __construct() { - $this->error = false; + $this->errors = []; + } + + protected final function addError($message, $fatal) + { + $this->errors[] = ['time' => time(), 'message' => $message, 'fatal' => $fatal]; } /** @@ -156,13 +165,13 @@ abstract class CourseBackend /** * Method for fetching the schedule of the given rooms on a server. * - * @param array $roomId array of room ID to fetch + * @param array $requestedLocationIds array of room ID to fetch * @return array|bool array containing the timetables as value and roomid as key as result, or false on error */ public final function fetchSchedule($requestedLocationIds) { if (!is_array($requestedLocationIds)) { - $this->error = 'No array of roomids was given to fetchSchedule'; + $this->addError('No array of roomids was given to fetchSchedule', false); return false; } if (empty($requestedLocationIds)) @@ -286,9 +295,18 @@ abstract class CourseBackend */ public final function getError() { + trigger_error('getError() is legacy; use getErrors()'); return $this->error; } + /** + * @return array list of errors that occured during processing. + */ + public final function getErrors() + { + return $this->errors; + } + /** * Query path in array-representation of XML document. * e.g. 'path/syntax/foo/wanteditem' @@ -349,13 +367,13 @@ abstract class CourseBackend * @param string $response xml document to convert * @return bool|array array representation of the xml if possible, false otherwise */ - protected function xmlStringToArray($response) + protected function xmlStringToArray($response, &$error) { $cleanresponse = preg_replace('/(<\/?)(\w+):([^>]*>)/', '$1$2$3', $response); try { $xml = @new SimpleXMLElement($cleanresponse); // This spams before throwing exception } catch (Exception $e) { - $this->error = 'Could not parse reply as XML, got ' . get_class($e) . ': ' . $e->getMessage(); + $error = get_class($e) . ': ' . $e->getMessage(); if (CONFIG_DEBUG) { error_log($cleanresponse); } diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php index ed3d7ec2..2b2b9d00 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php @@ -14,7 +14,7 @@ class CourseBackend_Davinci extends CourseBackend public function setCredentialsInternal($data) { if (empty($data['baseUrl'])) { - $this->error = "No url is given"; + $this->addError("No url is given", true); return false; } $location = preg_replace('#/+(davinciis\.dll)?\W*$#i', '', $data['baseUrl']); @@ -27,16 +27,17 @@ class CourseBackend_Davinci extends CourseBackend public function checkConnection() { if (empty($this->location)) { - $this->error = "Credentials are not set"; - } else { - $startDate = new DateTime('today 0:00'); - $endDate = new DateTime('+7 days 0:00'); - $data = $this->fetchRoomRaw('someroomid123', $startDate, $endDate); - if ($data !== false && strpos($data, 'DAVINCI SERVER') === false) { - $this->error = "Unknown reply; this doesn't seem to be a DAVINCI server."; - } + $this->addError("Credentials are not set", true); + return false; + } + $startDate = new DateTime('today 0:00'); + $endDate = new DateTime('+7 days 0:00'); + $data = $this->fetchRoomRaw('someroomid123', $startDate, $endDate); + if ($data !== false && strpos($data, 'DAVINCI SERVER') === false) { + $this->addError("Unknown reply; this doesn't seem to be a DAVINCI server.", true); + return false; } - return $this->error === false; + return true; } public function getCredentialDefinitions() @@ -87,11 +88,8 @@ class CourseBackend_Davinci extends CourseBackend curl_setopt_array($this->curlHandle, $options); $output = curl_exec($this->curlHandle); if ($output === false) { - $this->error = 'Curl error: ' . curl_error($this->curlHandle); + $this->addError('Curl error: ' . curl_error($this->curlHandle), true); return false; - } else { - $this->error = false; - ///Operation completed successfully } return $output; @@ -109,22 +107,20 @@ class CourseBackend_Davinci extends CourseBackend if ($return === false) { continue; } - $return = $this->xmlStringToArray($return); + $return = $this->xmlStringToArray($return, $err); if ($return === false) { - if (CONFIG_DEBUG) { - error_log('Room was ' . $roomId); - } + $this->addError("Parsing room $roomId XML: $err", false); continue; } $lessons = $this->getArrayPath($return, '/Lessons/Lesson'); if ($lessons === false) { - $this->error = "Cannot find /Lessons/Lesson in XML"; + $this->addError("Cannot find /Lessons/Lesson in XML", false); continue; } $timetable = []; foreach ($lessons as $lesson) { if (!isset($lesson['Date']) || !isset($lesson['Start']) || !isset($lesson['Finish'])) { - $this->error = 'Lesson is missing Date, Start or Finish'; + $this->addError('Lesson is missing Date, Start or Finish', false); continue; } $c = (int)$lesson['Date']; diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php index 94c967de..5807a4ff 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php @@ -21,12 +21,10 @@ class CourseBackend_Dummy extends CourseBackend $this->pw = $x['password']; if ($this->pw === "mfg") { - $this->error = false; return true; - } else { - $this->error = "USE mfg as password!"; - return false; } + $this->addError("USE mfg as password!", true); + return false; } /** @@ -35,12 +33,10 @@ class CourseBackend_Dummy extends CourseBackend public function checkConnection() { if ($this->pw == "mfg") { - $this->error = false; return true; - } else { - $this->error = "USE mfg as password!"; - return false; } + $this->addError("USE mfg as password!", true); + return false; } /** diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php index 1623755f..c61c3f2f 100755 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php @@ -82,7 +82,7 @@ class CourseBackend_Exchange extends CourseBackend try { $response = $client->ResolveNames($request); } catch (Exception $e) { - $this->error = $e->getMessage(); + $this->addError($e->getMessage(), true); return false; } @@ -92,7 +92,7 @@ class CourseBackend_Exchange extends CourseBackend return !empty($mailadress); } } catch (Exception $e) { - $this->error = $e->getMessage(); + $this->addError($e->getMessage(), true); } return false; } @@ -108,13 +108,13 @@ class CourseBackend_Exchange extends CourseBackend { foreach (['username', 'password'] as $field) { if (empty($data[$field])) { - $this->error = 'setCredentials: Missing field ' . $field; + $this->addError('setCredentials: Missing field ' . $field, true); return false; } } if (empty($data['serverAddress'])) { - $this->error = "No url is given"; + $this->addError("No url is given", true); return false; } @@ -166,7 +166,7 @@ class CourseBackend_Exchange extends CourseBackend try { $items = $this->findEventsForRoom($client, $startDate, $endDate, $roomId); } catch (Exception $e) { - $this->error .= "Failed to search for events for room $roomId: '{$e->getMessage()}'\n"; + $this->addError("Failed to search for events for room $roomId: '{$e->getMessage()}'", true); continue; } @@ -216,7 +216,7 @@ class CourseBackend_Exchange extends CourseBackend if ($response_message->ResponseClass !== ResponseClassType::SUCCESS) { $code = $response_message->ResponseCode; $message = $response_message->MessageText; - $this->error .= "Failed to search for events for room $roomAddress: '$code: $message'\n"; + $this->addError("Failed to search for events for room $roomAddress: '$code: $message'", true); continue; } $items = array_merge($items, $response_message->RootFolder->Items->CalendarItem); diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php index 2ffb9f41..809634ad 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php @@ -20,17 +20,16 @@ class CourseBackend_HisInOne extends CourseBackend // If not using OpenCourseService, require credentials foreach (['username', 'password'] as $field) { if (empty($data[$field])) { - $this->error = 'setCredentials: Missing field ' . $field; + $this->addError('setCredentials: Missing field ' . $field, true); return false; } } } if (empty($data['baseUrl'])) { - $this->error = "No url is given"; + $this->addError("No url is given", true); return false; } - $this->error = false; $this->username = $data['username']; if (!empty($data['role'])) { $this->username .= "\t" . $data['role']; @@ -65,11 +64,10 @@ class CourseBackend_HisInOne extends CourseBackend public function checkConnection() { if (empty($this->location)) { - $this->error = "Credentials are not set"; - } else { - $this->findUnit(123456789, date('Y-m-d'), true); + $this->addError("Credentials are not set", true); + return false; } - return $this->error === false; + return $this->findUnit(123456789, date('Y-m-d'), true) !== false; } /** @@ -100,22 +98,21 @@ class CourseBackend_HisInOne extends CourseBackend $soap_request = $doc->saveXML(); $response1 = $this->postToServer($soap_request, "findUnit"); - if ($this->error !== false) { + if ($response1 === false) { + $this->addError('Could not fetch room ' . $roomId, true); return false; } - $response2 = $this->xmlStringToArray($response1); + $response2 = $this->xmlStringToArray($response1, $err); if (!is_array($response2)) { - if ($this->error === false) { - $this->error = 'Cannot convert XML response to array'; - } + $this->addError("Parsing room $roomId: $err", false); return false; } if (!isset($response2['soapenvBody'])) { - $this->error = 'Backend reply is missing element soapenvBody'; + $this->addError('Backend reply is missing element soapenvBody', true); return false; } if (isset($response2['soapenvBody']['soapenvFault'])) { - $this->error = 'SOAP-Fault (' . $response2['soapenvBody']['soapenvFault']['faultcode'] . ") " . $response2['soapenvBody']['soapenvFault']['faultstring']; + $this->addError('SOAP-Fault (' . $response2['soapenvBody']['soapenvFault']['faultcode'] . ") " . $response2['soapenvBody']['soapenvFault']['faultstring'], true); return false; } // We only need to check if the connection is working (URL ok, credentials ok, ..) so bail out early @@ -131,7 +128,7 @@ class CourseBackend_HisInOne extends CourseBackend } $idSubDoc = $this->getArrayPath($response2, $path); if ($idSubDoc === false) { - $this->error = 'Cannot find ' . $path; + $this->addError('Cannot find ' . $path, false); //@file_put_contents('/tmp/findUnit-1.' . $roomId . '.' . microtime(true), print_r($response2, true)); return false; } @@ -139,7 +136,7 @@ class CourseBackend_HisInOne extends CourseBackend return $idSubDoc; $idList = $this->getArrayPath($idSubDoc, $subpath); if ($idList === false) { - $this->error = 'Cannot find ' . $subpath . ' after ' . $path; + $this->addError('Cannot find ' . $subpath . ' after ' . $path, false); @file_put_contents('/tmp/bwlp-findUnit-2.' . $roomId . '.' . microtime(true), print_r($idSubDoc, true)); } return $idList; @@ -201,10 +198,7 @@ class CourseBackend_HisInOne extends CourseBackend $output = curl_exec($this->curlHandle); if ($output === false) { - $this->error = 'Curl error: ' . curl_error($this->curlHandle); - } else { - $this->error = false; - ///Operation completed successfully + $this->addError('Curl error: ' . curl_error($this->curlHandle), false); } return $output; } @@ -239,14 +233,8 @@ class CourseBackend_HisInOne extends CourseBackend $ok = false; foreach ($currentWeek as $day) { $roomEventIds = $this->findUnit($roomId, $day, false); - if ($roomEventIds === false) { - if ($this->error !== false) { - error_log('Cannot findUnit(' . $roomId . '): ' . $this->error); - $this->error = false; - } - // TODO: Error gets swallowed + if ($roomEventIds === false) continue; - } $ok = true; $eventIds = array_merge($eventIds, $roomEventIds); } @@ -262,12 +250,8 @@ class CourseBackend_HisInOne extends CourseBackend //get all information on each event foreach ($eventIds as $eventId) { $event = $this->readUnit(intval($eventId)); - if ($event === false) { - error_log('Cannot readUnit(' . $eventId . '): ' . $this->error); - $this->error = false; - // TODO: Error gets swallowed + if ($event === false) continue; - } $eventDetails = array_merge($eventDetails, $event); } $name = false; @@ -286,9 +270,9 @@ class CourseBackend_HisInOne extends CourseBackend } $planElements = $this->getArrayPath($event, '/hisplanelements/hisplanelement'); if ($planElements === false) { - $this->error = 'Cannot find ./hisplanelements/hisplanelement'; - error_log('Cannot find ./hisplanelements/hisplanelement'); - error_log(print_r($event, true)); + $this->addError('Cannot find ./hisplanelements/hisplanelement', false); + //error_log('Cannot find ./hisplanelements/hisplanelement'); + //error_log(print_r($event, true)); continue; } foreach ($planElements as $planElement) { @@ -308,9 +292,9 @@ class CourseBackend_HisInOne extends CourseBackend $unitPlannedDates = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); if ($unitPlannedDates === false) { - $this->error = 'Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'; - error_log('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); - error_log(print_r($planElement, true)); + $this->addError('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate', false); + //error_log('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + //error_log(print_r($planElement, true)); continue; } $localName = $this->getArrayPath($planElement, '/hisdefaulttext'); @@ -366,15 +350,17 @@ class CourseBackend_HisInOne extends CourseBackend if ($response1 === false) { return false; } - $response2 = $this->xmlStringToArray($response1); - if ($response2 === false) + $response2 = $this->xmlStringToArray($response1, $err); + if ($response2 === false) { + $this->addError("Cannot parse unit $unit as XML: $err", false); return false; + } if (!isset($response2['soapenvBody'])) { - $this->error = 'Backend reply is missing element soapenvBody'; + $this->addError('Backend reply is missing element soapenvBody', true); return false; } if (isset($response2['soapenvBody']['soapenvFault'])) { - $this->error = 'SOAP-Fault (' . $response2['soapenvBody']['soapenvFault']['faultcode'] . ") " . $response2['soapenvBody']['soapenvFault']['faultstring']; + $this->addError('SOAP-Fault (' . $response2['soapenvBody']['soapenvFault']['faultcode'] . ") " . $response2['soapenvBody']['soapenvFault']['faultstring'], true); return false; } return $this->getArrayPath($response2, '/soapenvBody/hisreadUnitResponse/hisunit'); diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php index 377e960b..6cc71b3e 100644 --- a/modules-available/locationinfo/inc/locationinfo.inc.php +++ b/modules-available/locationinfo/inc/locationinfo.inc.php @@ -46,10 +46,25 @@ class LocationInfo * Set current error message of given server. Pass null or false to clear. * * @param int $serverId id of server - * @param string $message error message to set, null or false clears error. + * @param string|array $message error message to set, array of error message struct, null or false clears error. */ public static function setServerError($serverId, $message) { + if (is_array($message)) { + $fatal = false; + foreach ($message as $m) { + if ($m['fatal']) { + $fatal = $m['message']; + } + Database::exec('INSERT INTO locationinfo_backendlog (serverid, dateline, message) + VALUES (:sid, :dateline, :message)', [ + 'sid' => $serverId, + 'dateline' => $m['time'], + 'message' => ($m['fatal'] ? '[F]' : '[W]') . $m['message'], + ]); + } + $message = $fatal; + } if ($message === false || $message === null) { Database::exec("UPDATE `locationinfo_coursebackend` SET error = NULL WHERE serverid = :id", array('id' => $serverId)); -- cgit v1.2.3-55-g7522