2016-10-16 7 views
0

이 문제는 이미 문제를 해결했기 때문에 설명서 일 뿐이지 만 디버깅하기에는 미묘하고 어렵 기 때문에 공개 영역에서 유용하다고 생각했습니다.예외가 객체 메서드 내부에서 발견되지 않음

문제는 내가 작동하지 않는 개체 메서드에서 try/catch 블록을 가졌다는 것이 었습니다.

TestClass.php :

<?php 
//TestClass.php 
namespace MyTest; 

class TestClass { 
    public function __construct() { 
     \e("Initializing object"); 
     try { 
      \e("Trying object exception"); 
      \throwTestException("Failing gracefully in object"); 
      \e("After exception"); 
     } catch (Exception $e) { 
      \e($e->getMessage()); 
     } 
     \e("After object init exception"); 
    } 
} 
?> 

Main.php :로드 Main.php에

<?php 
//Main.php 

function e($str) { echo "\n$str"; } 
function throwTestException($msg) { 
    throw new RuntimeException($msg); 
} 
require "TestClass.php"; 

e("Beginning"); 
try { 
    e("First try"); 
    throwTestException("Failing gracefully first"); 
    e("After exception"); 
} catch (Exception $e) { 
    e($e->getMessage()); 
} 
e("Ending"); 

e(''); 

e('Beginning object test'); 
new \MyTest\TestClass(); 
e('Ending object test'); 
?> 

예상 결과이 있었다 감소 된 예는 다음과 같이 두 개의 파일에 있습니다 :

: 내가 실제로 가지고 무엇

Beginning 
First try 
Failing gracefully first 
Ending 

Beginning object test 
Initializing object 
Trying object exception 
Failing gracefully in object 
After object init exception 
Ending object test 

은 다음과 같이이었다

Beginning 
First try 
Failing gracefully first 
Ending 

Beginning object test 
Initializing object 
Trying object exception 

Fatal Error: Uncaught Exception: Failing gracefully in object...... 

보시다시피 예외는 발견되지 않았습니다. 나는 여러 가지 일을 시도했지만 왜 잡히지 않았는지 알 수 없었다. 그리고 .... (아래 답변 참조)

답변

0

네임 스페이스 문제라는 것을 깨달았습니다. 전역 공간에 TestClass 네임 스페이스 MyTestthrowTestException을 선언했기 때문에 클래스 메서드 내의 Exception에 대한 참조는 암묵적으로 \MyTest\Exception으로 확인되었고 throw 된 실제 예외 인 \RuntimeException과 일치하지 않았습니다. 그리고 실제로 네임 스페이스 내에서 예외를 인스턴스화하려고 시도하지 않았기 때문에 "알 수없는 클래스"오류가 발생하여 어떤 일이 발생했는지 알 수 없습니다.

솔루션, 다음, 제대로 내가 잡으려고 된 예외 클래스 해결하기 위해 간단했다 : 내 매우 감소 예를 내장으로

catch(\Exception $e) { .... } 

가 공정하게를,이 분명했다. 클래스의 수퍼 클래스 (SQLite3 클래스)가 catch 할 것으로 예상했던 예외가 생성 되었기 때문에 처음에는 명확하지 않았습니다. 따라서 예외를 생성 할 때 네임 스페이스에 대해 걱정할 필요가 없었습니다. 가장 일반적인 형식의 예외 인 Exception을 사용하는 것이 었습니다. 다시 말하면, 제가 예외를 인스턴스화하지 않았기 때문에 (catch 블록에서 일치하는 것만), 나는 그것이 해결되지 않았다는 통지를받지 못했습니다.

관련 문제