I use PHPUnit DataBase to test some class using MDB2.
All is well, since I encounter the second test, which returns an error:
Caught exception: Object of class
MDB2_Error could not be converted to
string
When I place the second test in place of the first one, the new first test is OK, but the second one returns the same error!
And the next ones also!
Maybe the MDB2 connection is closed after the first test?
Here is my constructor:
public function __construct()
{
$this->pdo = new PDO('connectionstring', 'user', 'passwd');
try {
$this->mdb2 = new MyDBA($this->dsn);
}
catch (Exception $e) {
error_log(' __construct Caught exception: '.$e->getMessage());
}
}
MyDBA returns a singleton.
No exception is raised inside the constructor...
Here are the two first tests:
public function testTranslationAdd()
{
try {
$id = $this->mdb2->addTranslation("This is the second english translation.","en");
}
catch (Exception $e) {
error_log(' testTranslationAdd Caught exception: '.$e->getMessage());
}
$xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/state/twotranslations.xml');
$this->assertDataSetsEqual($xml_dataset,
$this->getConnection()->createDataSet(array("translation")));
}
public function testTranslationGet()
{
try {
$text = $this->mdb2->getTranslation(1,"en");
}
catch (Exception $e) {
error_log(' testTranslationGet Caught exception: '.$e->getMessage());
}
$this->assertEquals("This is the first english translation.",$text);
}
You should really add assertions that your mdb2 result is no error:
$this->assertFalse(MDB2::isError($this->mdb2), 'MDB2 error');
That unfortunately does not give you any hint what the error is, and using getMessage() directly in the assertion will fail badly if you don't have an error. That why you should write something along that way:
if (MDB2::isError($this->mdb2)) {
$this->fail('MDB2 error: ' . $this->mdb2->getMessage());
}
Related
I am trying to use exception handling in case a file does not exists. For example when I run the model method and pass a string usr (which I know there is no file with that name) . It gives me the following error message
Fatal error: Uncaught exception 'Exception' with message 'Usr.php was not found' in /app/core/controller.php on line 14
I can't figure out whats wrong here. Can someone please help me figure this out?
Below is my code. Thanks alot!
class Controllers{
public function model($model){
if(!file_exists("../app/models/".$model.".php")) {
throw new exception("{$model}.php was not found");
}
try {
require ("../app/models/".$model.".php");
} catch(Exception $e) {
echo $e->getMessage();
}
return new $model();
}
}
You can't throw an exception without catching it; this automatically causes the PHP script to crash. So, you need to surround your entire function in the try-catch block, or the "model not found" exception will be uncaught. Your code should be something like this:
<?php
class Controllers {
public function model($model){
try {
if (!file_exists("../app/models/".$model.".php")) {
throw new Exception("{$model}.php was not found");
}
require ("../app/models/".$model.".php");
} catch(Exception $e) {
echo $e->getMessage();
}
return new $model();
}
}
Never mind guys! I found out I needed to use the try/catch blocks in the file where my method is being invoked
Example..
class Home extends Controllers{
public function index($name = ""){
try{
$user = $this->model('Usr');
}catch (Exception $e){
echo $e->getMessage();
}
//var_dump($user);
}
i have the following code and i'm wondering if i can use try & catch as below:
class fun_database implements idbInfo{
private $srvr=idbInfo::srvr_name;
private $usr=idbInfo::usrnm;
private $pass=idbInfo::psswrd;
private $db=idbInfo::db_name;
public function connct(){
$hookup = new mysqli($this->srvr, $this->usr, $this->pass, $this->db);
if ($hookup->connect_errno)
{
throw new Exception("Error Processing Request", 1);
}
}
public function sql_require_all($table_name, $table_col){
$hookup = new connct();
$result = $hookup->query("SELECT $table_col FROM $table_name");
if($hookup->error()){
throw new Exception("Error Processing Request", 1);
}
return $result->num_rows;
}
}
This is a simple connection to the mysql and performing some querying there. Here is and the actual call of the functions above:
$conn = new fun_database();
try{
$result = $conn->sql_require_all('wordtypes', 'types');
}
catch(Exception $err){
echo "Problems at:". $err->getMessage();
}
return "<option>".$result."</option>";
What i'm asking is a bit theory. Most probably this code is NOT WORKING (i didn't test it yet). I just want to know is it possible with one 'try' to 'catch' two exceptions (as you can see the first 'throw' is in the second method of fun_database, and the second 'throw' is in the first method of the same object which is only called from the second method).
sorry for making it too complicated but still can't figure it out id this structure of try/catch is working.
you can only catch different types of exception...
class fun_database implements idbInfo{
private $srvr=idbInfo::srvr_name;
private $usr=idbInfo::usrnm;
private $pass=idbInfo::psswrd;
private $db=idbInfo::db_name;
public function connct(){
$hookup = new mysqli($this->srvr, $this->usr, $this->pass, $this->db);
if ($hookup->connect_errno)
{
throw new DomainException("Error Processing Request", 1);
}
}
public function sql_require_all($table_name, $table_col){
$hookup = new connct();
$result = $hookup->query("SELECT $table_col FROM $table_name");
if($hookup->error()){
throw new Exception("Error Processing Request", 1);
}
return $result->num_rows;
}
}
Then:
try{
$conn = new fun_database();
$result = $conn->sql_require_all('wordtypes', 'types');
}
catch(DomainException $err){
echo "This Problem at:". $err->getMessage();
}
catch(Exception $err){
echo "That Problem at:". $err->getMessage();
}
return "<option>".$result."</option>";
you would need your class instantiation inside that try block though I believe.
It wouldn't catch the two exceptions because as soon as the first exception is thrown, it goes straight to the catch block, thereby skipping the second exception directly.
You could wrap each code which may throw an exception in its own try-catch block.
Yes and no. Your code is able to catch two of this exceptions but not both of them at the same time. When one of exception will be thrown, program execution will look for closest catch block, which fits to catch Exception class. Rest of code will be omitted.
You can throw an exception at an point in the program (not after an excpetion if it is not caught).
As soon as it hits this point it will stop and try to make the fallback to the a try catch block. As soon as it finds one it will do this block (if it is a good catch)
You could make a try catch around your entire program or just a function.
You can throw different classes of exceptions:
class ConnectException extends Exception {}
class QueryException extends Exception {}
and then catch different exceptions:
try {
// something
}
catch (ConnectException $ex) {
// connect exception
}
catch (QueryException $ex) {
// query exception
}
It is not possible because when you throw
throw new Exception("Error Processing Request", 1);
this exception it will be caught in this line
catch(Exception $err){
echo "This Problem at:". $err->getMessage();
}
you will not reach the line that can throw the other exception if first exception was thrown
I'm building a custom exception class to manage all exceptions:
class MyExceptions extends Exception
{
public function __construct($message = 'Unkown errror', $code = -1, Exception $previous = null) {
echo 'init!';
parent::__construct($message, $code, $previous);
}
}
Now, when a PDOException occurs, I want to re-throw it to MyExceptions:
class myDB
{
private $db;
public function dbConnect() {
try {
$this->db = new PDO('mysql:host=localhost;dbname=db;charset=utf8', 'user', 'pass');
}
catch (PDOException $e) {
throw new MyExceptions($e);
}
/* Updated */
catch (MyExceptions $e) {
echo 'caught!';
}
}
}
The problem is that when a db connection exception rises, I get the following fatal error on screen:
init!
Fatal error: Uncaught exception 'MyExceptions' with message...
So, the exception is not caught, although the MyExceptions __construct() is called (see the 'init!' displayed).
Every bit of resource I read points to the exact implementation as mine, I have no idea what I'm doing wrong.
You need
try {
try {
$this->db = new PDO('mysql:host=localhost;dbname=db;charset=utf8', 'user', 'pass');
} catch (PDOException $e) {
throw new MyExceptions($e);
}
} catch (MyExceptions $f) {
echo 'caught!';
}
Sequential catch blocks are for different types of exceptions thrown within the try.
You are throwing it:
throw new MyExceptions($e);
^^^^^
And then you don't catch it. So what do you wonder about?
Also you should add the previous exception at third position (for previous) instead of the first position (for message).
It doesn't go through all the catch blocks. Only the first one that matches. If you then throw another exception inside a catch block, you'd have to catch it in another try block around the first one.
My script_a.php:
try {
Class1::tryThis();
}
catch (Exception $e) {
// Do stuff here to show the user an error occurred
}
Class1::tryThis() has something like:
public function tryThis() {
Class2::tryThat();
self::logSuccessfulEvent();
}
The problem is that Class2::tryThat() can throw an exception.
If it does throw an exception, it seems that the line self::logSuccessfulEvent(); still gets executed.
How can I refactor this code so that self::logSuccessfulEvent() only occurs when an exception is not thrown, yet at the same time letting script_a.php know when an exception has been thrown?
This function will return whether or not the operation was successful (true = success, false = failure)
public function tryThis() {
$success = true;
try {
Class2::tryThat();
self::logSuccessfulEvent();
} catch( Exception $e) {
$success = false;
}
return $success;
}
What you're describing does not seem to be the case.
Code:
<?php
class Class1 {
public function tryThis() {
echo "Class1::tryThis() was called.\n";
Class2::tryThat();
self::logSuccessfulEvent();
}
public function logSuccessfulEvent() {
echo "Class1::logSuccessfulEvent() was called.\n";
}
}
class Class2 {
public function tryThat() {
echo "Class2::tryThat() was called.\n";
throw new Exception('Exception generated in Class2::tryThat()');
}
}
try {
Class1::tryThis();
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
Output:
Class1::tryThis() was called.
Class2::tryThat() was called.
Exception generated in Class2::tryThat()
As you can see, the Class1::logSuccessfulEvent() method is never executed when an exception is generated in Class2::tryThat(), and it shouldn't (won't) either. Exceptions bubble up until they are caught or produce a fatal error. Once an exception is caught, control of the program returns to the code after the catch block. In this particular case, that would mean that control of the program never reaches the logging method.
I am trying to understand what the best approach would be to handle Exceptions in the following scenario:
I have a class employee:
class employee extends person {
private $salary;
private $baseSalary = 6.5;
function __construct($f, $m, $l, $a,$fsalary=0){
if(!is_numeric($fsalary)){
throw new Exception("Age supplied is not a number", 114);
}
parent::__construct($f, $m, $l, $a);
$this->salary=$fsalary;
}
function GetDetails(){
return parent::GetName().
"<br/>".
$this->salary;
}
function __toString(){
return $this->GetDetails();
}
}
And using this:
try{
if(!$f = new employee("Sarah", "Sebastian", "Pira", "abc")){
throw new Exception();
}
else {
echo $f;
}
}
catch (Exception $e){
echo "<br/>";
echo var_dump($e);
}
Now I would think it would be a good idea to throw an exception in the class and then use just one catch block in all the scripts that would be using an employee object - But this doesn't seem to work - I need to have a try catch block within the class - Is this the correct way of looking at this?
Thanks
I think what you're saying is that you want to do something like this:
try {
class Employee extends Person {
// ...blah blah...
}
}
catch(Exception $e) {
// handle exception
}
...and then be able to insantiate it in other classes, without explicitly catching any exceptions:
// try { << this would be removed
$employee = new Employee();
// }
// catch(Exception $e) {
// (a whole bunch of code to handle the exception here)
// }
You can't do that, because then the try/catch block in the class will only catch any exceptions that occur when defining the class. They won't be caught when you try to instantiate it because your new Employee line is outside the try/catch block.
So really, your problem is that you want to be able to re-use a try/catch block in multiple places without re-writing the code. In that case, your best solution is to move the contents of the catch block out to a separate function that you can call as necessary. Define the function in the Employee class file and call it like this:
try {
$employee = new Employee();
$employee->doSomeStuff();
$employee->doMoreStuffThatCouldThrowExceptions();
}
catch(Exception $e) {
handle_employee_exception($e);
}
It doesn't get rid of the try/catch block in every file, but it does mean that you don't have to duplicate the implementation of the exception-handling all the time. And don't define handle_employee_exception as an instance method of the class, do it as a separate function, otherwise it will cause a fatal error if the exception is thrown in the constructor because the variable won't exist.
You should read more about Exceptions in PHP.
You can handle exceptions within the methods of the class, sure. But you should rethink how you want to do this and... why.
Good practice is also creating own exception class, so you are able to distinguish exceptions thrown by your module / class from the exceptions thrown by something else. It looks like that (see more):
class EmployeeModule_Exception extends Exception {}
and when it comes to throwing exception:
// the second parameter below is error code
throw new EmployeeModule_Exception('some message', 123);
Catching is similar, only the below example will catch only your module's exceptions:
try {
// some code here
} catch (EmployeeModule_Exception $e) {
// display information about exception caught
echo 'Error message: ' . $e->getMessage() . '<br />';
echo 'Error code: ' . $e->getCode();
}