function a() {
try {
$name = "Mary";
$e = new Exception("INTENTIONAL ERROR FROM a()", 5); // Notice that my string message is very short, and I gave it an error code of 5
throw new Exception($e); // Then I throw the exception
} catch (Exception $e) {
// But this next statement gives a loooooong message ,much more than I specified. How can I make it just display
// what I specified, no more and no less?
echo "I'm in a()'s catch block [[" . $e->getCode() . ']] : [[' . $e->getMessage() . ']]<br/>';
throw new Exception($e);
}
}
function b() {
try {
a();
} catch(Exception $e) {
echo "I'm in b()'s catch block [[" . $e->getCode() . ']] : [[' . $e->getMessage() . ']]<br/>';
}
}
b();
I'm in a()'s catch block [[0]] : [[INTENTIONAL ERROR FROM a()]]
I'm in b()'s catch block [[0]] : [[INTENTIONAL ERROR FROM a()]]
I'm in a()'s catch block [[0]] : [[exception 'Exception' with message 'INTENTIONAL ERROR FROM a()' in C:\xampp\htdocs\newdimension\public\test\test.php:8 Stack trace: #0 C:\xampp\htdocs\newdimension\public\test\test.php(18): a() #1 C:\xampp\htdocs\newdimension\public\test\test.php(24): b() #2 {main}]]
I'm in b()'s catch block [[0]] : [[exception 'Exception' with message 'exception 'Exception' with message 'INTENTIONAL ERROR FROM a()' in C:\xampp\htdocs\newdimension\public\test\test.php:8 Stack trace: #0 C:\xampp\htdocs\newdimension\public\test\test.php(18): a() #1 C:\xampp\htdocs\newdimension\public\test\test.php(24): b() #2 {main}' in C:\xampp\htdocs\newdimension\public\test\test.php:9 Stack trace: #0 C:\xampp\htdocs\newdimension\public\test\test.php(18): a() #1 C:\xampp\htdocs\newdimension\public\test\test.php(24): b() #2 {main}]]
[/When you echo an object, the __toString() method gets called
If the only thing you're going to throw is Exception, why not just use die()
The reason I put it this way is that Exception by itself is kind of useless
I know how to use exceptions, and I do not condemn the concept.
but if you don't have a recovery path what would you do with the exception
I've never seen any use to throw Exception in the Exception handler, and I'm a little surprised that PHP even allows that
I'll go back and try to make sense of the first code sample here.
Finally, suggesting Ray will abuse his power as a moderator by changing your grade from a C to an A is totally unacceptable and you owe him an apology.
<?php // demo/temp_elepil.php
/**
* SEE http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28658286.html#a40731380
* REF http://php.net/manual/en/language.exceptions.php
* http://php.net/manual/en/class.exception.php
* http://php.net/manual/en/exception.construct.php
*/
error_reporting(E_ALL);
echo '<pre>';
function a() {
// THIS CODE BLOCK WILL THROW AN EXCEPTION
try {
// THIS VARIABLE IS NOT USED IN THE SCRIPT SO I COMMENTED IT OUT
// $name = "Mary";
// THIS ATTEMPTS UNDOCUMENTED BEHAVIOR. WE DO NOT INSTANTIATE EXCEPTION OBJECTS, WE THROW THEM
$e = new Exception("INTENTIONAL ERROR FROM a()", 5); // Notice that my string message is very short, and I gave it an error code of 5
// SHOW WHAT IS PRESENT IN $e (NOT A STRING, AS CALLED FOR IN THE DOCUMENTATION)
var_dump($e);
echo PHP_EOL;
// THIS WILL THROW AN EXCEPTION USING THE $e VARIABLE AS A STRING. SINCE $e IS NOT A STRING, PHP WILL CALL __toString()
throw new Exception($e); // Then I throw the exception
// THIS CODE BLOCK WILL CATCH THE EXCEPTION THROWN IN THE TRY BLOCK ABOVE
// THEN IT WILL THROW ANOTHER EXCEPTION -- BUT TO WHAT LOGICAL EFFECT?
} catch (Exception $e) {
// But this next statement gives a loooooong message ,much more than I specified. How can I make it just display
// what I specified, no more and no less?
// SHOW WHAT IS PRESENT IN $e NOW = AN EXCEPTION OBJECT
var_dump($e);
echo PHP_EOL;
// THIS WILL PRINT OUT SOME INFORMATION FROM THE $e EXCEPTION OBJECT
echo "I'm in a()'s catch block [[" . $e->getCode() . ']] : [[' . $e->getMessage() . ']]<br/>';
// THIS WILL THROW A NEW EXCEPTION REPEATING THE SAME MISTAKE ABOVE - USING AN OBJECT IN PLACE OF THE EXPECTED STRING
// PROBABLY THIS EXCEPTION WILL GET CAUGHT INSIDE OF THE b() FUNCTION
throw new Exception($e);
}
}
function b() {
// THIS CODE BLOCK WILL TRY THE FUNCTION a() THAT WILL THROW AN EXCEPTION AND CATCH THE EXCEPTION INSIDE a()
try {
a();
// THIS CODE BLOCK WILL CATCH THE LAST THROWN EXCEPTION AND ASSIGN IT TO $e
} catch(Exception $e) {
// SHOW WHAT IS PRESENT IN $e NOW = AN EXCEPTION OBJECT
var_dump($e);
echo PHP_EOL;
echo "I'm in b()'s catch block [[" . $e->getCode() . ']] : [[' . $e->getMessage() . ']]<br/>';
}
}
// THIS WILL START THE CASCADE OF TRY {} CATCH{} PROCESSES
b();
I hope this is helping. If not, please post back with any questions. And if we say, "don't do that," please understand that we have reasons for saying these things - we know most of the right ways to use PHP and if you can tell us what you want to do in plain, non-technical language, we can usually come up with a "best practices" approach to the problem.
As always, var_dump() is our friend. You can use it to inspect the properties of objects.
FWIW, I have never seen correct programming that throws the same exception from inside the block that catches the exception, so I would be inclined to redesign that code.
Now with that said, let's gather some code references that describe the objects you're dealing with:
The base class for all Exceptions:
http://php.net/manual/en/class.exception.php There are only four properties, and a handful of getter methods.
The base class constructor:
http://php.net/manual/en/exception.construct.php
There are many articles that detail the strategies for using Exceptions. My friend Brandon Savage has an introductory here that is pretty good (this is stuff you already know, but expressed in PHP terms).
http://www.brandonsavage.net/exceptional-php-introduction-to-exceptions/
How to write and handle exceptional conditions? Start with the premise that Exception is only a base class and consider it unusable without your extensions. If the only thing you're going to throw is Exception, why not just use die()? The reason I put it this way is that Exception by itself is kind of useless. It's the base class without any meaning or recovery mechanisms, and if you can't recover from an Exception, it should not be an exceptional condition, it should be considered a fatal condition. There is no more information unless your code adds the information by extending the Exception class and building an error object that gives useful details about your unique exceptional condition.
To give an example, consider the PDOException. There are many reasons a database can "hiccup" and only some of them are fatal. One of the recoverable PDO exceptions can arise when you try to INSERT a duplicate into a column marked UNIQUE. In that case PDO will throw a PDOException with error number 1062. You can catch this error number and retry the INSERT with different data. That is a useful way of working with an exception. Another useful way (for developers) would be to catch the error number and SQLSTATE, and translate that numeric information into href-links to the related documentation. The exception handler that caught PDOException could display this information so the developer would immediately see a clickable link to the documentation that described corrective practices.
PHP offers exception chaining but it's a little lame - most of the built-in PHP exceptions do not know about the "previous" property. And as many smart people have discovered, exception chains introduce the same cognitive load that we had with GOTO statements. It's like multiple inheritance - just don't do that.
Here is a little piece of code that can show you how PHP Exceptions work. It's descriptive (not prescriptive) and intended only to illustrate the logic and show the contents of the Exception object. Try it a few different ways to see what it does.
http://iconoun.com/demo/try_throw_catch.php?q=0
http://iconoun.com/demo/try_throw_catch.php?q=1
http://iconoun.com/demo/try_throw_catch.php?q=2
http://iconoun.com/demo/try_throw_catch.php?q=3
Open in new window