Hey There,
Today, I'm proud to be putting up my first "guest post" and would like to thank Herschel Cohen for his outstanding contribution!
BTW, this page looks a lot better when it's not trapped in a blog post ;)
Without further ado, but some padding to keep the title from wrapping around...
Here's to your enjoyment :)
Web Site
Developers
Programming PHP: Implicit OO Code in Error Catching Structure
Learning from Errors
I have written on other occasions, you can learn more seeing errors others commit, whatever their cause, which can be more instructive than simply spelling out how to do it correctly. It simply might be the relief of not finding oneself trapped in the same predicament that makes the lesson more likely to stick. This time it was the try / catch code syntax that trapped me. It seemed too transparent and too easily understood, which resulted in my missing a critical aspect. That is today's topic of discussion.
I will make no attempt to explain my reasoning, it's just too unique to my background and to my warped mind. Nonetheless, I am sure others could find themselves in the same predicament. So I will focus on how I was fooled and my circuitous route towards enlightenment. See this too as my filing in the holes I left in my last article on catching the missing file error where I used the afore mentioned syntax.
Impression of try {} catch {} Code Syntax
When I was on a programming contract [1.], I took part in Java code reviews. I had the impression I could read and understand [2.] Java code. I was attracted to the try / catch code syntax, which appeared quite straight forward. That is, place the code you wish to run within the try section and if it fails it is automatically shifted to the catch section. There given enough specified exceptions the possibility existed to save the program from an ignominious crash. Moreover, in Java [3.], I thought that the ending "finally" section could allow full recovery. Nonetheless, many of my perceptions were fallacious.
Mistaken Impressions - How it Started
My mistakes began early, with the popping up of fairly complete descriptions of encountered errors I saw when testing methods to display missing menu names. In the attempt to redirect the error to a separate page, I mentioned seeing a ephemeral error message that was fired well within the template at the readfile() line for the menu listing. Moreover, later when I was explicitly testing for the file missing error it was painted onto the page in the location the menu listing should have appeared:
Figure 1. Automated Error Message
If you look closely at the content of the message above, it appears nearly identical to Example #3 The Built in Exception class. So while I knew an instance of the class had to be present, the error messages seemed to confirm the exception object was both present and functioning. Nonetheless, my try / catch code was not working properly. Below, I am repeating the outline of the code I used in other articles. Here is the section where the menu listing is read into the template:
<div id="central-col-bst">
<?php
if ($if_error==false) { // adding new error catching code 5/31/2008
try {
readfile($menus . "/menu-list-".$get_it.".txt");
} catch (move_onException $e) {
$if_error = true;
// only action flips the variable
}
} else {
$gohome = $_SERVER['DOCUMENT_ROOT']."/page-content/navigation";
readfile($menus."/messages/menu-not-known.txt");
readfile($gohome."/home-button.txt");
}
if ($if_error==true) {
// This is were the email is sent when the
// text file is missing, then the error
// message is painted where the menu
// listing would have fallen.
} else {
echo "\n\n Code has run by email";
}
?>
</div?> <!-- End of central Product News column --?>
Listing 1 Code Structure to Catch readfile() errors
So I inserted additional code within the try section to determine why my code was failing:
<div id="central-col-bst">
<?php
if ($if_error==false) { // adding new error catching code 5/31/2008
try {
readfile($menus . "/menu-list-".$get_it.".txt");
$level = error_reporting();
$val = error_reporting(E_WARNING);
print "Error value $level <br />";
print "Warning error value is $val <br />";
} catch (move_onException $e) {
$if_error = true;
// only action flips the variable
}
...
Listing 2 Modified Code in try section
Now look at the output when this version was run:
Figure 2. Exception Object Not Functioning
Note the last line, "Code has run by email" indicating the variable was not flipped to true. Thus, the catch part of the code was never entered. Something is badly amiss with the object that is firing.
Java Explanation
Once I began to read [4.] about the object model of Java it became clear the object that was live and printed the messages was an instance of the Error class not the Exception(s). Below I have a graphic that is a modified version of the one in the book (cited in footnote 4). The Error class object was the one posting the error messages. The code failed to fire on the catch section, because no instance of the Exception object was available for use:
Figure 3. Java Object for Errors & Exceptions
Therefore, it is obvious that object orientated code is an implicit part of the try / catch syntax, which might not be immediately obvious if the documentation were not studied.
Revised Error Catching Code
I am going to do little other than exhibit a simpler version of the code I showed in the last article. This time I will not use a subclass of the Exception class, hence, there is no need to store the class definition on the page. Creating an instance of the Exception suffices, because I am not using for any reason than reaching the catch section of the code. Here is the skeleton of the code that enhances Listing 1 slightly:
<div id="central-col-bst">
<?php
if ($if_error==false) { // adding new error catching code 5/31/2008
try {
$file_exists = file($menus . "/menu-list-".$get_it.".txt");
if ($file_exists === FALSE) {
throw new Exception($e);
} else {
readfile($menus . "/menu-list-".$get_it.".txt");
}
} catch (move_onException $e) {
$if_error = true;
// only action flips the variable
}
} else {
$gohome = $_SERVER['DOCUMENT_ROOT']."/page-content/navigation";
readfile($menus."/messages/menu-not-known.txt");
readfile($gohome."/home-button.txt");
}
if ($if_error==true) {
// This is were the email is sent when the
// text file is missing, then the error
// message is painted where the menu
// listing would have fallen.
} else {
echo "\n\n Code has run by email";
}
?>
</div?> <!-- End of central Product News column --?>
Listing 3 Working Code Structure to Catch Missing File Errors
Extending Exception Object Model
I mentioned my dissatisfaction with the increasing volume of code where similar processes that differ slightly are appearing in multiple location on the page template. I have not tested out these ideas, however, it is not a great stretch to use a subclass of the Exception class to contain new methods that email differing messages to the webmaster based upon a variable determined by the error type. The same might work for a customized error message that is painted on the page. For those that like to compress their code, the try / catch syntax and printing of either the menu listing or error messages could be buried within a method in a new subclass. However, if you go that route, be prepared to document your intentions so that anyone that follows can maintain your site in your absence.
Summary
Once the object model operating characteristic are understood as part of the try / catch exceptions, indeed the syntax is relatively straight forward. Moreover, there are multiple exceptions be tested with all residing in a common subclass that is used repeatedly throughout an application. Such use should deflate the overall size of the application's code and increase its reliability.
Corrections, suggested extension or comments write: H. Cohen. If the mailto does not work, use this: hcohen[-At-]bst-softwaredevs.com.
© Herschel Cohen, All Rights Reserved
Return B/ST Home or Dynamic Menu Page
____________________________________________________________________
1. Mostly writing stored procedures for Sybase on Unix and
associated financial reporting. Return
2. I had not written a line of Java code.
Return
3. Not part of the php syntax.Return
4. See the same numbered footnote in my last article.
Chapter 11 in "Core Java 2; Volume 1 - Fundamentals" has a
version of the graphic I display in the text. Error
objects have an existing instance and fire when needed to
stop the program. The Exception object has to be created.
Return
References
, Mike