2016-07-01 2 views
2

Im работает над классом, чтобы SVN менялся с помощью приложения PHP. Я вызываю команды svn через exec() и пытаюсь исключить исключение из ошибки, чтобы отменить любые изменения.PHP Исключение не поймано

Вот соответствующая часть класса SVN:

private function svn_exec($cmd) { 
     $out = array(); 
     $err = 0; 
     exec($cmd, $out, $err); 

     if ($err) { 
      throw new SVNException("$cmd exited with a status of $err"); 
     } 
    } 

И пользовательские исключения, содержащаяся в том же файле, что и класс SVN:

class SVNException extends \Exception { 
    public function __construct($message = null, $code = 0, \Exception $previous = null) { 

     error_log("SVN Error: " . $message); 

     parent::__construct("A Subversion error has occurred.", $code, $previous); 
    } 
} 

И коды вызова в другом классе :

public function ApplySVNChanges() { 
    try { 
       $svn->update(); 

       // Do a bunch more stuff... 

       $svn->commit(); 
      } catch (\utils\SVNException $se) { 
       error_log("Exception caught in SVN class."); // <-- Being logged 
       $svn->revert(); 
       throw $se; // Throw to caller so db changes are rolled back 
      } 
} 

Обновление SVN бросает исключение SVNException, прежде чем я смогу перейти к тому, что мне нужно чтобы выяснить, что приложение сбой, и не обрабатывает исключение SVNException, как должно. В соответствии с журналами ошибок исключение SVNException не обрабатывается. Вызов $ svn-> update() находится в блоке try/catch, который должен улавливать SVNExceptions, поэтому я смущен тем, почему он не обрабатывается.

PHP Fatal error: Uncaught exception 'utils\SVNException' with message 'A Subversion error has occurred.' in /path/SVNFunctions.php:114\nStack trace:\n#0 /path/SVNFunctions.php(73): utils\SVNFunctions->svn_exec('svn update --us...')\n#1 /path/CallingClass.php(120)

Update: После добавления сообщений в улове блоки для входа, когда исключения ловятся, я обнаружил, что исключение SVN быть пойманным, но когда вызвана повторно метода над ним, что вызывает его не поймать его. Исходный блок try catch является частью метода, который вызывается другим методом со своим собственным блоком, чтобы отменить изменения SVN и db, чтобы синхронизировать их.

try { 
     ApplySVNChanges(); // Throws SVNException 

     // Database related changes...   

     $db-commit(); 
    } catch (Exception $e) { 
     error_log('Caught Exception in main caller.'); // <-- NOT being logged 

     if($e instanceof \core\DatabaseException OR $e instanceof \utils\SVNException) {   
      $db->rollback(); 
     } else { 
      throw $e; 
     } 
    } 

В соответствии с журналами ошибок команда update выбрасывает исключение. Он улавливается первым уловом, вызывается возврат, а catch в вызывающем методе для баз данных и исключений SVN не улавливает его.

ответ

0

Обнаружили проблему. Блок примерки улов, содержащий вызовы других методов, которые бросают SVNException:

catch (Exception $e) { 
     if($e instanceof \core\DatabaseException OR $e instanceof \utils\SVNException) {   
      $db->rollback(); 
     } else { 
      throw $e; 
     } 
} 

был на самом деле не ловить SVNExceptions или DatabaseExceptions. Добавление обратной косой черты перед Exception исправлена ​​проблема:

catch (\Exception $e) { 

В SVNExceptions решаются, как предполагалось.

Редактировать: Для любопытных этот ответ на другой вопрос: https://stackoverflow.com/a/12170579/5530617 действительно решил проблему, которая вызывала $ svn-> update(), чтобы сгенерировать исключение, добавив параметр --config-dir в команду оболочки.

+0

Ааааа .... Пространство имен – Martin

1

Как вы поживаете svn->revert()? может ли быть так, что svn->revert() вызывает svn->exec или делает что-то еще, что делает исключение реброзом?

Я просто угадал, но если Revert мог не бросить и SVNException я думаю, что это случается здесь ..

Вы могли бы проверить, просто изменяя крылатую часть, с чем-то вроде echo "test"; exit; вместо $svn->revert();

UPDATE: После вашего обновления, вы добавили опечатку, изменить $throw se к throw $se,

public function ApplySVNChanges() { 
try { 
      $svn->update(); 

      // Do a bunch more stuff... 

      $svn->commit(); 
     } catch (\utils\SVNException $se) { 
      error_log("Exception caught in SVN class."); // <-- Being logged 
      $svn->revert(); 
      throw $se; // Throw to caller so db changes are rolled back 
     } 

}

+0

Я добавил сообщения поймать блоки, чтобы определить, когда исключения пойманы, то SVNException из обновлений является фактически поймано, REVERT вызывается, и исключение из обновлений брошено, но не попало в примерках улове от вызывающего, вопроса обновляется , – tylero

+0

убрать изменения могут бросить свое собственное исключение, но намерение состоит в том, что исключение попадет в вызывающем методе дальше. Кроме того, только для тестирования я поставил db-> REVERT линии в своем собственной примерке поймать блок для входа, когда это произойдет, и ничто не становится выброшено из него. – tylero

+0

нашли опечатку в своем обновлении вопрос, так что я обновил свой ответ как хорошо –