diff --git a/includes/FeedsSource.inc b/includes/FeedsSource.inc index 2fe2249..f7f314f 100644 --- a/includes/FeedsSource.inc +++ b/includes/FeedsSource.inc @@ -783,6 +783,7 @@ class FeedsSource extends FeedsConfigurable { if (!lock_acquire("feeds_source_{$this->id}_{$this->feed_nid}", 60.0)) { throw new FeedsLockException(t('Cannot acquire lock for source @id / @feed_nid.', array('@id' => $this->id, '@feed_nid' => $this->feed_nid))); } + set_error_handler(array($this, 'errorHandler')); } /** @@ -790,6 +791,55 @@ class FeedsSource extends FeedsConfigurable { */ protected function releaseLock() { lock_release("feeds_source_{$this->id}_{$this->feed_nid}"); + restore_error_handler(); + } + + /** + * Handles errors during importing, clearing, and expiring. + * + * @see set_error_handler() + */ + public function errorHandler($error_level, $message, $filename, $line, $context) { + if ($error_level & error_reporting()) { + // If this is NOT a recoverable error, attempt to clean up. + // @todo: Does this make sense or do we know that if an error was not + // recoverable we can't clean up? + // @todo: It may be safer to delete the state every time when loading it. + if ($this->handleError($error_level, $message, $filename, $line, $context)) { + unset($this->state); + $this->save(); + } + _drupal_error_handler($error_level, $message, $filename, $line, $context); + } + } + + /** + * Logs error and determines whether error is fatal. + * + * @return bool + * TRUE if error is fatal, FALSE otherwise. + */ + protected function handleError($error_level, $message, $filename, $line, $context) { + require_once DRUPAL_ROOT . '/includes/errors.inc'; + + $levels = drupal_error_levels(); + list($severity_message, $severity_level) = $levels[$error_level]; + + $backtrace = debug_backtrace(); + // Remove the FeedsSource::errorHandler() call. + array_shift($backtrace); + $caller = _drupal_get_last_caller($backtrace); + + $variables = array( + '@message' => $message, + '%function' => $caller['function'], + '%file' => isset($caller['file']) ? $caller['file'] : '', + '%line' => isset($caller['line']) ? $caller['line'] : '', + ); + + $this->log('import', '@message
%function
%file
%line', $variables, $severity_level); + + return $error_level & array(E_ERROR | E_COMPILE_ERROR | E_COMPILE_ERROR | E_USER_ERROR); } }