Proper way to create a Exception class factory - php

In PHP the exception object does not get updated when thrown, as cHao pointed out, thank you!.
So in a Exception class factory function this function get's blamed for the Exception and not the location where it eventually is thrown. :-/
What is a suggested why to circumvent this predicament?

Related

Storing a PHP exception object in a database

I have need to store a PHP Exception object in a mysql column. It's for an offline error logging system. Usually I would just serialize() the Exception object and be done with it, but half the time, when trying to do that, I get the following error:
Fatal error: Uncaught exception 'Exception' with message
'Serialization of 'Closure' is not allowed'
I am not sure how to get this to work consistently. I will greatly appreciate anyone who has an answer to this problem.
Thanks.
The exception object to be logged contains an instance of Closure class, PHP's implementation of anonymous functions and closure. Apparently anonymous functions cannot be serialized.
You need to investigate your exception classes and see if any of them is supposed to contain them. Normally, exception classes shouldn't have an anonymous function as property.
This reproduces the same error message as your case:
$exception = new Exception('BOO');
$anonymousFunction = function() { echo 'blah'; };
$exception->anonymousFunction = $anonymousFunction;
serialize($exception);
So dig in through your code, your framework's code, your library's code, and try to find out which exception class did have an anonymous function as class property, who assigned them, why - and then you should be able to create a special case for it.
Hope this helps.
http://php.net/manual/en/function.set-error-handler.php
here's the global error handler definition function. you can define a global error handler and make it write the error description to the database.
And the structure of the exception class :
http://php.net/manual/en/class.exception.php

Zend framework how to handle exceptions

What is the best practice for throwing an Exception in the following situation:
My URL structure is:
/articles/view/id/1
My Controller:
AticlesController
And this controller loads a Mapper model:
Application_Model_Mapper_Articles
In this model I aggregate all kinds of data. I check several criteria in this model to decide between throwing a 404 error or showing the article.
If I decide to throw the error. How should I do it?
My first guess was throwing it from within the model. But there is no default 'Model_Exception' class and there is a 'Zend_Controller_Action_Exception'. Should I just throw this exception from within the model? Or should I pass the error message back from the model to the controller and then throw the error?
Model itself should not interfere with the FrontController, so yes, throw the exception from the controller.
You may throw an exception from the model (not Zend_Controller_Action_Exception, but some that more precisely describes your problem), catch it in the controller and on that base decide if you're gonna throw Zend_Controller_Action_Exception or not.
You could create an Application_Model_Mapper_Articles_Exception, and you could either choose to handle that in your controller and throw exceptions to the error controller, or use your exception code to designate the type of HTTP response code to set.

Why does mock object have wrong type hint?

Trying to do a simple mock of Zend_Config for a method that requires a Zend_Config object type, but the mock returns a type of Mock_Zend_Config.
Surely I missed something at this late hour and I am obviously wrong in the function call but I fail to spot my error.
$config = $this->getMock("Zend_Config");
Returns Mock_Zend_Config, and my object needs to be of type Zend_Config. Looked up the function signature in a cheatsheet and changed the method call to:
$config = $this->getMock("Zend_Config", array(), array($confArray),"Zend_Config",true);
This version generates a fatal error with message "Zend_Config already exists".
On a sidenote and probably not related to phpunit as such but the typehint does not generate a fatal error as it should , and does so when run without tests.
Any idea of what I'm missing in la mock?
Mock objects extend the mocked object. A type hint for Zend_Config will be satisfied by any class extending Zend_Config because by definition a Mock_Zend_Config extends Zend_Config and therefor is a Zend_Config. Consequently, you will get a Fatal Error when trying to name the mock like the class it extends and none if you dont.

"Cannot override final method Exception::__clone()"

I'm getting the following strange error message whenever I attempt to run my script.
There is nothing I could see that would be causing the problem - in fact, the only thing in my script right now that deals with exceptions at all (they are the building blocks of a future addition) are the following lines:
class NoMatchingRouteException extends \RuntimeException { }
class HandlerException extends \RuntimeException { }
class HandlerMissingException extends HandlerException { }
class HandlerInaccessibleException extends HandlerException { }
These are various exceptions that form a tree of various exceptions I can throw.
Nowhere in here am I ever overriding the Exception class's __clone magic method, so I can't see where the problem is occurring.
I understand that, as it stands, my question may be hard to answer - thus, if you have any ideas where I should look for the problem and or what additional code I should look for to post, please post them in the comments and I will try to reply ASAP.
Thanks.
I've had this error when I mistakenly used
include
for an overridden exception class twice.
When I changed back to include_once, the error went away.
This error appears when you define class more than once. So avoid defining classes inside functions and use require_once for .inc files.
I managed to rid myself of the strange error (albeit accidentally) when I changed some architecture. I agree that the error is very weird, and would love to post the class in question - unfortunately, I can't revert back to it (I know, I know. ;). Thanks!

Using a code for an exception. Useful?

I am not sure if Exceptions work the same way in each language, but I am using PHP and I was wondering when I'm doing something like this:
if (!$this->connection[0]->query($this->query))
throw new QueryFailedException($this->connection[0]->error);
Is there a need to supply a code in the second parameter? For example:
if (!$this->connection[0]->query($this->query))
throw new QueryFailedException($this->connection[0]->error,123);
Now the code is 123... I can't think of a need for this. Is there one? In this case the message contains the query, exception name is QueryFailedException which explains the exception type, the exception itself contains file, line and stack trace, so, I can't think of anything where you could use the code for something useful.
The error code was a feature used when there was no object oriented language. The only thing that could aid you to understand what went wrong was the error code. In an object oriented language, the object IS your error code.
Unless, in specific cases, more than one thing can throw the exact same error AND they are treated in different ways, drop it.
Also, you would provide much better explanation to whomever is debugging your code if you left a message instead of a meaningless error code, so if you feel like the exception needs more information, fill the Error Message field instead.
The error code is a field that can be used to provide more detailed information. If for example you have two things that can generate the same exception, the code could be used to give more detail.
If you have an "error source" that works on error codes and you "promote" it to exceptions you can include the actual error code in the exception. a) it does no harm and b) maybe you do not want to have an exception class for each single error code that may or may not occur (and virtually no one cares for in a running system).
Let's take the MySQL server errors as an example. You could create one class for each of those codes
class MySQLException_ER_HASHCHK extends MySQLException
class MySQLException_ER_NISAMCHK extends MySQLException
class MySQLException_ER_NO extends MySQLException
class MySQLException_ER_YES extends MySQLException
class MySQLException_ER_CANT_CREATE_FILE extends MySQLException
class MySQLException_ER_CANT_CREATE_TABLE extends MySQLException
class MySQLException_ER_CANT_CREATE_DB extends MySQLException
class MySQLException_ER_DB_CREATE_EXISTS extends MySQLException
class MySQLException_ER_DB_DROP_EXISTS extends MySQLException
....
but in reality ...who cares? Who's really gonna catch them individually? In almost all cases there will only be a catch(MySQLException $mex) in the app's code and maybe, just maybe it's looking for one specific code where it makes little to no difference for the coder whether there are two catch-blocks or an if/switch block. Now you have a lot of "dead" classes and no one -except the parser- gives a damn about them. (on the other hand "everything worth doing is worth overdoing it")
And even if you do provide some granularity I think it makes little sense to go beyond e.g. having one exception class for each SQLState (does that make sense? sqlstate? don't know, just an example)
class MySQLException_HY000 extends MySQLException
class MySQLException_HY001 extends MySQLException
class MySQLException_XA100 extends MySQLException
class MySQLException_XA102 extends MySQLException
And then again you probably want to include the error code - why lose this information even though/even if your code usually doesn't evaluate it?
If you can, it is very good to set in an exception code.
That is if you don't change your code to throw different exceptions based on the data you get from your database.
The error code, in OOP is the Exception Class Name itself, so that you can interpret each of them in just one try but with multiple catch clauses.
try {
// code here
} catch (AccessDeniedException $e) {
// do something
} catch (Exception $e) {
// do something else
}

Categories