Перехват собственных исключений
Я создаю пакет с собственными исключениями, но при попытке перехватить исключение получаю фатальную ошибку: Uncaught exception. Эта ситуация возникает только когда метод с исключением вызывается через add_action( 'init', array( $this, 'wp_some_method' ) );
Пример:
class SomeClass {
public function __construct() {
add_action( 'init', array( $this, 'wp_some_method' ) );
echo '__constructor<br />';
}
function some_method(){
throw new \Exception('сообщение об ошибке');
}
function wp_some_method( $post_type ){
throw new \Exception('Вторая ошибка');
}
}
try{
echo 'try <br />';
$o = new SomeClass();
//$o->some_method(); - здесь исключение перехватывается правильно
} catch (\Exception $ex) {
echo $ex->getMessage();
}
На экране отображается:
try
__constructor
И затем: Fatal error: Uncaught exception 'Exception'

Ваше исключение не перехватывается блоком try{} catch(){}, потому что оно не выбрасывается внутри этого блока. Это демонстрирует непонимание асинхронных событий и системы хуков/действий/событий WordPress.
Методы вашего объекта прикреплены к хуку действия init и выбрасываются при срабатывании хука init, а не при создании объекта и не при их прикреплении.
Например:
class SomeClass {
public function __construct() {
// когда происходит действие/событие init, вызывается метод wp_some_method
add_action( 'init', array( $this, 'wp_some_method' ) );
}
function wp_some_method( $post_type ){
throw new \Exception('ошибка');
}
}
try{
// отлично, исключения не было при создании объекта
$o = new SomeClass();
} catch (\Exception $ex) {
echo $ex->getMessage();
}
// спустя некоторое время где-то в ядре WordPress...
do_action( 'init' ); // метод, который мы прикрепили к хуку init, выбросил исключение, но не было ничего, чтобы его перехватить!
Ваш метод не вызывается при создании объекта. Он прикреплен к событию init, но не вызывается, именно потому что событие 'init' еще не произошло. Событие init происходит значительно позже выполнения вашего блока try{} catch.
Вместо этого более подходящими будут следующие варианты:
- добавить try catch в методы класса (лучший вариант)
- не выбрасывать исключения в функциях, прикрепленных к хукам/событиям (еще лучше)
- выбрасывать исключение в новом методе, который не прикреплен, чтобы можно было добавить try catch (нормально, требует хорошего разделения ответственности и абстракции)
- добавить глобальный обработчик ошибок (костыль, настоятельно не рекомендуется, займет больше времени, чем стоит, может перехватывать другие исключения, которые вы не планировали перехватывать)
В противном случае нет рациональной, логической или здравой причины, по которой строка кода с throw new \Exception
должна выполняться внутри блока try catch, как у вас выше, без вашего явного вызова вручную, как вы это сделали в тесте.
