How useful have you found this? Personally I find it a much of a muchness, with PHP's internal error handling often getting in the way, and sometimes throwing the same errors that you would throw anyway.I like it, the fact that it's object oriented makes it that much easier to group your errors together, also it allows you add extra functionality into your error handling. For example, you may want run some checks on the network if more than ten network erros occur. Now, network error could be pretty high up your class hierarchy and therefore the count/check could be triggered by a whole host of more specific subclassed errors. This may not be the best example but I hope it gives an idea of the flexibilty available with this kind of error handling framework.I agree that there are alot of useful scenarios, but I think the implementation is quite poor. For example:
<?php
$a = 1;
$b = 2;
class a {}
try {
// This is great
if($a != $b){
throw new Exception("blah blah");
}
// This isn't (comment out class a, set $b to 1)
if(!$a = new a()){
// This exception never gets thrown due to internal handling
throw new Exception("blah blah");
}
}catch(Exception $e){
trigger_error($e->getMessage(), E_USER_ERROR);
}
?>
In addition to this, some of the new class (the Iterators) throw their own Exceptions, so you need to nest try blocks in order to catch the Exceptions with your custom handlers.
If I'm missing something blindingly obvious, please enlighten me You have to know each class's API, but then that would be the same for anyone else using your classes. Rather than throwing your own errors you should be using theirs. Either catch them and handle them or allow them to bubble up to be handled elsewhere. It's seems counter-productive to catch and throw for what is essentially the same error.
NB.
Can you allow Exceptions to bubble without explicitly catcing and throwing them at each stage? I am assuming this is the same as in Java as so much else in the framework is but I am not sure.The point is really that PHP functions and statements (not classes) can generate errors which are uncatchable, so you can't do anything about it.
Here's an example of nested error handling, I don't think errors bubble up to the top due to typing, but I'm not too sure.
function __construct($data){
/* SimpleXMLIterator throws it's own Exception */
try {
try {
$this->xml = new SimpleXMLIterator($data);
/* Rethrow Exception to our custom handler */
}catch(Exception $e){
throw new NavigatorException($e->getMessage(), get_class($this));
}
}
catch(NavigatorException $e){
echo $e->toFullString();
exit;
}
}
Removing the nested catch causes a fatal error (Parse error: parse error, unexpected '}', expecting T_CATCH)I don't get what you're trying to do here. I don't see the logic in throwing and catching an error in the same method and I'm suprised it's even allowed. Surely the reason for throwing an error is to notify classes higher up the stack that an error as taken place. I would suggest removing the outer try all together and have it handled by whoever's calling it.Yep that makes more sense actually, that client code gets notified of errors rather than handling them internally.
I learned how the Exception class worked mainly from this article (<!-- m --><a class="postlink" href="http://www.sitepoint.com/article/coming-soon-webserver-near/13">http://www.sitepoint.com/article/coming ... er-near/13</a><!-- m -->), which at the bottom mentions something about internal errors getting in the way of the Exception class.From the article
try {
$db = new SQLite('/www/sitepoint/php5/sitepoint.sqlite');
try {
# Simulate bad connection
// throw new IOError('Lost connection to database');
$result = $db->query('SELECT * FROM users');
while ( $row = $result->fetch() ) {
echo ( '<pre>' );
print_r($row);
echo ( '</pre>' );
}
} catch ( SQLError $e ) {
echo ( 'There is something wrong with the query: '.$e->getMessage() );
} catch ( Exception $e ) {
// Re-throw exception
throw ($e);
}
} catch ( IOError $e ) {
echo ( 'Major problems!' );
error_log ( date('YmdHis').": ".$e->getMessage()."\n",3,'errors.txt' );
} catch ( Exception $e ) {
echo ( 'Hmmm - no idea how to deal with this: '.$e->getMessage() );
}
I'd be really dissapointed if that's how we had to handle the possibility of multiple errors being thrown. In Java you can have as many catch clauses per try as you like so this could be re-written as.
try {
$db = new SQLite('/www/sitepoint/php5/sitepoint.sqlite');
# Simulate bad connection
// throw new IOError('Lost connection to database');
$result = $db->query('SELECT * FROM users');
while ( $row = $result->fetch() ) {
echo ( '<pre>' );
print_r($row);
echo ( '</pre>' );
}
} catch ( SQLError $e ) {
echo ( 'There is something wrong with the query: '.$e->getMessage() );
} catch ( IOError $e ) {
echo ( 'Major problems!' );
error_log ( date('YmdHis').": ".$e->getMessage()."\n",3,'errors.txt' );
} catch ( Exception $e ) {
echo('Hmm - no idea how to deal with this: '.$e->getMessage());
}
which makes much more sense to me. You just start off with the more specific Exceptions and lead down the more general (ending with the most general, ie Exception).Can you allow Exceptions to bubble without explicitly catcing and throwing them at each stage? I am assuming this is the same as in Java as so much else in the framework is but I am not sure.
Sure I read somewhere that if you don't want to catch an exception you can throw it again so another, higher layer can catch it
You just throw them and an exception will be caught next layer.Currently, the main problem with PHP5 Exceptions is the amount of misinformation and unfounded speculation being passed around. There is a big ongoing discussion in the PEAR development mailing list on using exceptions. At least a third of the posts are just plain wrong.
If you are thinking about using exceptions then wrtie some code and see how they work. Don't rely on someone else's opinion on how they might work.
Now I'll go ahead and contradict myself by suggesting that people read this:
<!-- m --><a class="postlink" href="http://pear.php.net/pepr/pepr-proposal-show.php?id=132">http://pear.php.net/pepr/pepr-proposal-show.php?id=132</a><!-- m -->
It's poorly named but mostly accurate. And browse the related wiki.
<?php
$a = 1;
$b = 2;
class a {}
try {
// This is great
if($a != $b){
throw new Exception("blah blah");
}
// This isn't (comment out class a, set $b to 1)
if(!$a = new a()){
// This exception never gets thrown due to internal handling
throw new Exception("blah blah");
}
}catch(Exception $e){
trigger_error($e->getMessage(), E_USER_ERROR);
}
?>
In addition to this, some of the new class (the Iterators) throw their own Exceptions, so you need to nest try blocks in order to catch the Exceptions with your custom handlers.
If I'm missing something blindingly obvious, please enlighten me You have to know each class's API, but then that would be the same for anyone else using your classes. Rather than throwing your own errors you should be using theirs. Either catch them and handle them or allow them to bubble up to be handled elsewhere. It's seems counter-productive to catch and throw for what is essentially the same error.
NB.
Can you allow Exceptions to bubble without explicitly catcing and throwing them at each stage? I am assuming this is the same as in Java as so much else in the framework is but I am not sure.The point is really that PHP functions and statements (not classes) can generate errors which are uncatchable, so you can't do anything about it.
Here's an example of nested error handling, I don't think errors bubble up to the top due to typing, but I'm not too sure.
function __construct($data){
/* SimpleXMLIterator throws it's own Exception */
try {
try {
$this->xml = new SimpleXMLIterator($data);
/* Rethrow Exception to our custom handler */
}catch(Exception $e){
throw new NavigatorException($e->getMessage(), get_class($this));
}
}
catch(NavigatorException $e){
echo $e->toFullString();
exit;
}
}
Removing the nested catch causes a fatal error (Parse error: parse error, unexpected '}', expecting T_CATCH)I don't get what you're trying to do here. I don't see the logic in throwing and catching an error in the same method and I'm suprised it's even allowed. Surely the reason for throwing an error is to notify classes higher up the stack that an error as taken place. I would suggest removing the outer try all together and have it handled by whoever's calling it.Yep that makes more sense actually, that client code gets notified of errors rather than handling them internally.
I learned how the Exception class worked mainly from this article (<!-- m --><a class="postlink" href="http://www.sitepoint.com/article/coming-soon-webserver-near/13">http://www.sitepoint.com/article/coming ... er-near/13</a><!-- m -->), which at the bottom mentions something about internal errors getting in the way of the Exception class.From the article
try {
$db = new SQLite('/www/sitepoint/php5/sitepoint.sqlite');
try {
# Simulate bad connection
// throw new IOError('Lost connection to database');
$result = $db->query('SELECT * FROM users');
while ( $row = $result->fetch() ) {
echo ( '<pre>' );
print_r($row);
echo ( '</pre>' );
}
} catch ( SQLError $e ) {
echo ( 'There is something wrong with the query: '.$e->getMessage() );
} catch ( Exception $e ) {
// Re-throw exception
throw ($e);
}
} catch ( IOError $e ) {
echo ( 'Major problems!' );
error_log ( date('YmdHis').": ".$e->getMessage()."\n",3,'errors.txt' );
} catch ( Exception $e ) {
echo ( 'Hmmm - no idea how to deal with this: '.$e->getMessage() );
}
I'd be really dissapointed if that's how we had to handle the possibility of multiple errors being thrown. In Java you can have as many catch clauses per try as you like so this could be re-written as.
try {
$db = new SQLite('/www/sitepoint/php5/sitepoint.sqlite');
# Simulate bad connection
// throw new IOError('Lost connection to database');
$result = $db->query('SELECT * FROM users');
while ( $row = $result->fetch() ) {
echo ( '<pre>' );
print_r($row);
echo ( '</pre>' );
}
} catch ( SQLError $e ) {
echo ( 'There is something wrong with the query: '.$e->getMessage() );
} catch ( IOError $e ) {
echo ( 'Major problems!' );
error_log ( date('YmdHis').": ".$e->getMessage()."\n",3,'errors.txt' );
} catch ( Exception $e ) {
echo('Hmm - no idea how to deal with this: '.$e->getMessage());
}
which makes much more sense to me. You just start off with the more specific Exceptions and lead down the more general (ending with the most general, ie Exception).Can you allow Exceptions to bubble without explicitly catcing and throwing them at each stage? I am assuming this is the same as in Java as so much else in the framework is but I am not sure.
Sure I read somewhere that if you don't want to catch an exception you can throw it again so another, higher layer can catch it
You just throw them and an exception will be caught next layer.Currently, the main problem with PHP5 Exceptions is the amount of misinformation and unfounded speculation being passed around. There is a big ongoing discussion in the PEAR development mailing list on using exceptions. At least a third of the posts are just plain wrong.
If you are thinking about using exceptions then wrtie some code and see how they work. Don't rely on someone else's opinion on how they might work.
Now I'll go ahead and contradict myself by suggesting that people read this:
<!-- m --><a class="postlink" href="http://pear.php.net/pepr/pepr-proposal-show.php?id=132">http://pear.php.net/pepr/pepr-proposal-show.php?id=132</a><!-- m -->
It's poorly named but mostly accurate. And browse the related wiki.