CodeIgniter: Try Catch не работает в классе модели

У меня есть unique ограничение для столбца. Когда этот код работает, я получаю журнал ошибок из фреймворка, но это не то, что я дал в блоке исключений.
Если существует уникальный столбец, я хочу запросить его первичный ключ и установить его как $id и вернуться на страницу. Сейчас он останавливается на ошибке db и не входит в Catch block .
Вот мой код:

 try { $result = $this->db->insert('email', $new_email); if ($result) { $id = $this->db->insert_id(); } else { throw new Exception("$$$$$$$$$$$$$Log database error"); } } catch (Exception $e) { log_message('error',$e->getMessage()); return; } 

**Error Messages** Я получаю из фреймворка:

 DEBUG - 2013-04-07 05:00:38 --> DB Transaction Failure ERROR - 2013-04-07 05:00:38 --> Query error: Duplicate entry 

Я не знаю, что с ним не так.

У CI нет хорошей поддержки для исключений. Запросы DB будут вызывать некоторые неопределенные CI error_logging thingy, называемые show_error (). Что вам нужно сделать, это настроить правильную обработку исключений.

В основном вы можете следовать всему рецепту.

Теперь все ваши ошибки базы данных будут автоматически генерировать исключения. И в качестве бонуса у вас есть хорошая обработка исключений во всем приложении CI.

Зарегистрируйте настраиваемый обработчик ошибок, который преобразует ошибки PHP в исключения, например, помещает это в начало вашего config / config.php

 function my_error_handler($errno, $errstr, $errfile, $errline) { if (!(error_reporting() & $errno)) { // This error code is not included in error_reporting return; } log_message('error', "$errstr @$errfile::$errline($errno)" ); throw new ErrorException( $errstr, $errno, 0, $errfile, $errline ); } set_error_handler("my_error_handler"); 

Зарегистрируйте обработчик неперехваченных исключений, добавьте что-то вроде этого в config / config.php

 function my_exception_handler($exception) { echo '<pre>'; print_r($exception); echo '</pre>'; header( "HTTP/1.0 500 Internal Server Error" ); } set_exception_handler("my_exception_handler"); 

Установите обработчик завершения:

 function my_fatal_handler() { $errfile = "unknown file"; $errstr = "Fatal error"; $errno = E_CORE_ERROR; $errline = 0; $error = error_get_last(); if ( $error !== NULL ) { echo '<pre>'; print_r($error); echo '</pre>'; header( "HTTP/1.0 500 Internal Server Error" ); } } register_shutdown_function("my_fatal_handler"); 

Установите настраиваемый обработчик assert, который преобразует утверждения в исключения, добавьте что-то вроде этого в config / config.php:

 function my_assert_handler($file, $line, $code) { log_message('debug', "assertion failed @$file::$line($code)" ); throw new Exception( "assertion failed @$file::$line($code)" ); } assert_options(ASSERT_ACTIVE, 1); assert_options(ASSERT_WARNING, 0); assert_options(ASSERT_BAIL, 0); assert_options(ASSERT_QUIET_EVAL, 0); assert_options(ASSERT_CALLBACK, 'my_assert_handler'); 

Используйте такие обертки в ваших контроллерах

 public function controller_method( ) { try { // normal flow } catch( Exception $e ) { log_message( 'error', $e->getMessage( ) . ' in ' . $e->getFile() . ':' . $e->getLine() ); // on error } } 

Вы можете настроить и настроить все по своему вкусу!

Надеюсь это поможет.

Вам также необходимо перехватить метод CI show_error. Поместите это в application / core / MY_exceptions.php:

 class MY_Exceptions extends CI_Exceptions { function show_error($heading, $message, $template = 'error_general', $status_code = 500) { log_message( 'debug', print_r( $message, TRUE ) ); throw new Exception(is_array($message) ? $message[1] : $message, $status_code ); } } 

И оставить в application / config / database.php этот параметр в FALSE, чтобы ошибки базы данных были преобразованы в исключения.

 $db['default']['db_debug'] = TRUE; 

У CI есть несколько (очень) слабых мест, таких как обработка исключений, но это будет долго исправлять это.

Если вы собираетесь использовать транзакции, убедитесь, что вы выполняете откаты на исключениях. В связи с этим НИКОГДА (как и в EVER) использование постоянных подключений в качестве открытых транзакций и другого состояния DB для конкретного сеанса будет поднято / продолжено другими сеансами.

Если включена отладка базы данных, ошибки из БД будут перенаправлены в основной класс Исключения, а exit() вызывается после, что означает, что сценарий никогда не достигнет вашего условного условия if .

Откройте application/config/database.php и попробуйте установить db_debug на false. Это хорошая идея для создания веб-сайтов, так или иначе, потому что вы не хотите, чтобы какие-либо проблемы с SQL-запросом вывела информацию о вашей структуре базы данных.

Кроме того, не связанный с этим, будьте осторожны, используя $ внутри двойных кавычек, потому что он будет анализироваться как переменная (даже куча из них в строке – это будет буквально переменная переменная переменная …).

Что делать, если вы устанавливаете результат вне блока try ? Или тройной оператор:

 $result = $this->db->insert('email', $new_email); try { $result = ($result) ? $result || false; if ($result) { $id = $this->db->insert_id(); } else { throw new Exception("$$$$$$$$$$$$$Log database error"); } } catch (Exception $e) { log_message('error',$e->getMessage()); return; } 

Трудно понять, не зная, какова ценность $result , как, например, @jcorry.