I have a mysqli call ($result = $this->mysqli->query($query)
) in which $query
is an insert statement that generates the error: "Duplicate entry 'dt' for key 'username_UNIQUE'";. I have set the mysqli reporting mode with
\mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
The callstack at this point is about 8 methods deep, and there are several try-catch blocks along the way.
Finally there is a try-catch block in index.php, the outermost block of code. The exception seems to be ignoring all the deeper try-catch blocks, but is caught in the outermost one. Not sure if it matters, but all code blocks are in class methods except for the code in index.php.
To demonstrate this problem, I'll show you index.php and the first method called from index.php.
<?php
define('DS',DIRECTORY_SEPARATOR);
define('APP_START',microtime(true));
define('ROOT_DIR',dirname(__FILE__).DS);
define('FW_DIR',sprintf("%svendor%sfw%s",ROOT_DIR,DS,DS));
define('APP_DIR',sprintf( '%sapp%s',ROOT_DIR,DS));
try {
// set up the autoloader
require sprintf('%sbootstrap%sbootstrap.php',FW_DIR,DS);
// next, set up the factory for all future class instantiation
$factory = new fw\factory\ClassFactory();
// create the app
$app = $factory->getClass('app\app');
// process the request
$ob = "";
$result = $app->go();
// return anything in the output buffer then the application output
echo $ob.$result;
} catch (Exception $e) {
die("Caught Exception in index.php: ".$e->getMessage());
}
I have determined that the above code executes into $app->go()
, but does not reach the line echo $ob.$result;
.
Now here's the $app class:
<?php
namespace app;
class App extends \fw\app\App
{
protected $trace = false;
public function __construct(protected \fw\exception\ErrorHandler $errorhandler,
protected \fw\session\WebSession $session,
protected \app\http\RequestHandler $requesthandler,
protected \database\MySqlDB $db
) {
parent::__construct();
}
public function go(){
try {
$this->requesthandler->init($this->errorhandler,$this->session,$this->db);
$result = $this->requesthandler->processrequest(false);
} catch (Exception $e) {
die(__METHOD__." : ".$e->__toString());
}
return $result;
}
}
I have determined that the code enters $this->requesthandler->processrequest(false);
. Many method calls deeper it reaches the insert statement that triggers the exception.
The output from the above is "Caught Exception in index.php: Duplicate entry 'dt' for key 'username_UNIQUE'" which clearly comes from the catch in index.php. My question is, why does the code not die in the catch block in the $app class (or any of the other try-catches deeper in the stack).
Your App
class is specified to be using
namespace app;
which means that the classes referenced will be looked for inside this namespace
. Therefore, your
try {
//some code
} catch (Exception $e) {
//some code
}
will catch any Exception
object inside the app
namespace, that is, any \app\Exception
that might be thrown. The actual exception that is thrown is an instance of \Exception
and hence it will not be caught with the catch
that you have. You could have
} catch (\Exception $e) {
for example and that's the full namespace name of the Exception
class whose instances you intended to catch.
Look into aliasing and importing as well as namespaces for more information.