2013-06-21 6 views
6

Я написал тест PHPUnit, который проверяет, выбрано ли исключение из закрытия при вызове метода. Функция закрытия передается в качестве аргумента методу с исключением из него.Почему мое исключение выбрасывается из замыкания, которое не было поймано?

public function testExceptionThrownFromClosure() 
{ 
    try { 
     $this->_externalResourceTemplate->get(
      $this->_expectedUrl, 
      $this->_paramsOne, 
      function ($anything) { 
       throw new Some_Exception('message'); 
      } 
     ); 

     $this->fail("Expected exception has not been found"); 
    } catch (Some_Exception $e) { 
     var_dump($e->getMessage()); die; 
    } 
} 

Код функции задавалась на ExternalResourceTemplate является

public function get($url, $params, $closure) 
{ 
    try { 
     $this->_getHttpClient()->setUri($url); 
     foreach ($params as $key => $value) { 
      $this->_getHttpClient()->setParameterGet($key, $value); 
     } 
     $response = $this->_getHttpClient()->request(); 
     return $closure($response->getBody()); 
    } catch (Exception $e) { 
     //Log 
     //Monitor 
    } 
} 

Любые идеи, почему называется провал заявление утверждают? Можете ли вы не поймать исключения, выброшенные из замыканий на PHP, или есть конкретный способ борьбы с ними, о котором я не знаю.

Для меня исключение должно просто распространять исходный стек, но он не отображается. Это ошибка? FYI Я бегу PHP 5.3.3

+1

Вы можете попасть только в том же объеме, что и бросок. Внутренний охват в этом отношении оторван от внешнего. Я не знаю языка, в котором поведение в противном случае. –

+0

Спасибо Beetroot-Beetroot, что было на самом деле проблемой. Блок catch никогда не вызывается в тесте, потому что исключение было проглочено в классе ExternalResourceTemplate –

+0

. Я не совсем уверен, что вы оба имеете в виду то же самое. Нераспространение исключения отличается от отсутствия исключения в другом стеке вызова/разматывания. Во всяком случае, как правило, наличие блока catch исключительно для ведения журнала: do not ;-) – VolkerK

ответ

2

Спасибо за ответы ...

Удалось решить проблему. Похоже, проблема заключается в том, что вызываемый блок try-catch, который вызывается, является тем, где вызывается замыкание. Который имеет смысл ...

Так выше код должен быть

public function get($url, $params, $closure) 
{ 
    try { 
     $this->_getHttpClient()->setUri($url); 
     foreach ($params as $key => $value) { 
      $this->_getHttpClient()->setParameterGet($key, $value); 
     } 
     $response = $this->_getHttpClient()->request(); 
     return $closure($response->getBody()); 
    } catch (Exception $e) { 
     //Log 
     //Monitor 
     throw new Some_Specific_Exception("Exception is actually caught here"); 
    } 
} 

Так это выглядит, как PHP 5.3.3 не ошибка, после все, что было сказано. Виноват.

0

Я не могу воспроизвести поведение, мой пример сценария

<?php 
class Some_Exception extends Exception { } 
echo 'php ', phpversion(), "\n"; 
$foo = new Foo; 
$foo->testExceptionThrownFromClosure(); 

class Foo { 
    public function __construct() { 
     $this->_externalResourceTemplate = new Bar(); 
     $this->_expectedUrl = '_expectedUrl'; 
     $this->_paramsOne = '_paramsOne'; 
    } 

    public function testExceptionThrownFromClosure() 
    { 
     try { 
      $this->_externalResourceTemplate->get(
       $this->_expectedUrl, 
       $this->_paramsOne, 
       function ($anything) { 
        throw new Some_Exception('message'); 
       } 
      ); 

      $this->fail("Expected exception has not been found"); 
     } catch (Some_Exception $e) { 
      var_dump('my exception handler', $e->getMessage()); die; 
     } 
    } 
} 

class Bar { 
    public function get($url, $p, $fn) { 
     $fn(1); 
    } 
} 

отпечатки

php 5.4.7 
string(20) "my exception handler" 
string(7) "message" 

, как ожидается,

+0

Интересно ... спасибо! Разная версия PHP. Мне придется подумать об этом еще немного. –

+0

Я только что попробовал это с версией от php-5.3.3-Win32-VC9-x86.zip от http://windows.php.net/downloads/releases/archives/, и вывод все тот же (кроме версии число конечно ;-)) – VolkerK