XML_PullParser
A token-based interface to the PHP expat XML library
version 1.3.2
Myron Turner
Error Reporting

Contents         

When an XML_PullParser method returns False, it signals an error. 1 XML_PullParser_Errors is the class that identifies and tracks the errors. Tracking comes into play because XML_PullParser methods often call other XML_PullParser methods. In other words, the original source of an error may not be in the method called by the user's code but in another that this method calls.

The basic error messages include an error string which describes the error, any context-specific error strings, and the line number and function where the error occurred. When error tracking is invoked, the error trace includes the basic error information plus the defined name of the error and the error number.

The user interface to this class is through a set of package level functions. Following are the defined errors and the package level variables and functions which are used for error reporting.


Defined Error Constants and their Associated Messages Strings
  1. XML_PullParser_ERROR_SYSTEM
    Uknown System Error
  2. XML_PullParser_ERROR_MISMATCHED_TAGS
    Mismatched tags: child element declared in $tags array or read buffer too small
  3. XML_PullParser_ERROR_NO_DATA
    No Data Available
  4. XML_PullParser_ERROR_NO_DEFAULT_TOKEN
    Default token missing: no current token or $current_element found
  5. XML_PullParser_ERROR_NO_TOKEN
    No Token Available
  6. XML_PullParser_ERROR_BAD_PARAM
    Missing or Wrong Parameter
  7. XML_PullParser_ERROR_BAD_INTERNAL_ARRAY
    Required Internal Array Missing, Corrupt, or Empty
  8. XML_PullParser_ERROR_USER_DEFINED
    User defined error
  9. XML_PullParser_ERROR_NS_SUPPORT
    NamespaceSupport has not been invoked


Package Level Variables
  1. $XML_PullParser_ERROR_DEF
    An array that holds that string names of the defined error constants, so that $XML_PullParser_ERROR_DEF[0] returns "XML_PullParser_ERROR_SYSTEM"
  2. $XML_PullParser_ERROR
    An array of the error strings produced by each defined error, such that $XML_PullParser_ERROR[DEFINED_ERROR_CONSTANT] or $XML_PullParser_ERROR[$error_number] will return the appropriate error string.
  3. $XML_PullParser_Errors_lastError
    This holds the entire contents of the last error, including the defined error string, any context-specific string, and the line number and function where the error occurred.
  4. $XML_PullParser_Errors_errorStack
    This is an array of references to XML_PullParser_Errors objects. The are pushed onto the array as the errors occur, so that $XML_PullParser_Errors_errorStack[0] is the oldest error. This stack is used by XML_PullParser_Errors_Trace to produce its trace.
  5. $XML_PullParser_Errors_lastErrNum
    The error number of the last error.

Package Level Functions
XML_PullParser_Errors is accessed through a set of package level functions. These include two functions which enable the user to define and access errors in the user's own scripts.
  1. void XML_PullParser_Errors_errMsg ()
    Returns the current error message. This includes the defined error string plus any context-specific message.
  2. void XML_PullParser_Errors_Num ()
    Returns the current Error number. This will be one of the defined constants. Its string name can be obtained from $XML_PullParser_ERROR_DEF using the error number returned from this function.
  3. void XML_PullParser_Errors_Ref ()
    Returns an XML_PullParser_Errors object popped from an internal stack which holds all errors up to and including the last (i.e. current) error. It is used by XML_PullParser_Errors_Trace to output the trace. Once the trace is done the stack is empty. This means that if you pop an error off this stack yourself, then the trace will not inlcude the popped error.
  4. void XML_PullParser_Errors_Trace ()
    Prints out a trace of errors up to and including the current error.
  5. XML_PullParser_Errors XML_PullParser_Errors_userDefined (string $msg)
    This function takes a string $msg and returns an XML_PullParser_Errors object. Once the error is created is is treated exactly as an XML_PullParser_Errors which is created by XML_PullParser . It will be placed on the trace stack and returned in any trace carried out by XML_PullParser_Errors_Trace.
  6. string XML_PullParser_Errors_getUserDefined (mixed $obj)
    This function takes the XML_PullParser_Errors object which is returned by XML_PullParser_Errors_userDefined and returns the error message constructed for the error.

Now we can look at an example of how to use the error checking interface. Admittedly, this first example is a bit artificial. That is, it calls XML_PullParser_getElement without having first called XML_PullParser_getToken, which is the basis for all the other calls.

Listing 21
 1.    $tags = array("Entry");
 2.    $child_tags = array("server");
 3.    $parser = new XML_PullParser("DNS.xml",$tags,$child_tags);
 4.     
 5.    $parser->XML_PullParser_getElement("server");
 6.  
 7.    while($next = $parser->XML_PullParser_nextElement()) {
 8.         $data = $parser->XML_PullParser_getText($next);
 9.         echo $data ."\n";  
10.    }
11.    if($next === FALSE) {
12.       echo XML_PullParser_Errors_errMsg() . "\n";
13.       echo "\n";
14.       echo XML_PullParser_Errors_Trace() . "\n";
15.    }

The result of this is as follows, where the first error message comes from XML_PullParser_Errors_errMsg and the remainder from the trace function:

No token returned: XML_PullParser_nextElement requires a prior call 
                                                            to XML_PullParser_getElement
Line: 1714, function: XML_PullParser_nextElement


------Error Trace------------
ERROR:  No token returned: XML_PullParser_nextElement requires a prior call
                                                                to XML_PullParser_getElement
Line: 1714, function: XML_PullParser_nextElement
Error Number: 4  (XML_PullParser_ERROR_NO_TOKEN)

ERROR:  Required Internal Array Missing, Corrupt, or Empty:
        XML_PullParser_getToken must be called before XML_PullParser_getElement
Line: 2582, function: XML_PullParser_getElement
Error Number: 6  (XML_PullParser_ERROR_BAD_INTERNAL_ARRAY)

-----End Trace:-------------

The errors in the trace are reported in reverse order, that is, the most recent error is reported first and the oldest error is reported last. Let's look at a more realistic bug, which might be something like the following:

Listing 22
 
 
 1.    $tags = array("DNS");
 2.    $child_tags = array("Entry");
 3.    $parser = new XML_PullParser("DNS.xml",$tags,$child_tags);     
 4.
 5.     while($token = $parser->XML_PullParser_getToken()) 
 6.     {
 7.         $entry = $parser->XML_PullParser_getElement("entry");      
 8.         $child = $parser->XML_PullParser_getChild("server",2,$entry);     
 9.         $child = $parser->XML_PullParser_getText("server",2,$entry);     
10.         echo "Server: $child\n";
11.         $attr_array = $parser->XML_PullParser_getAttributes("server", 2, $child);
12.         if($attr_array) {
13.         foreach($attr_array as $n => $v) {
14.                echo "$n -- $v\n";
15.          }
16.        }
17.         elseif($attr_array === FALSE) {
18.           echo XML_PullParser_Errors_Trace() . "\n";
19.           exit;
20.        }    
21.    }

Here we have one of those little bugs that can creep into one's code. In line 11, the third parameter to XML_PullParser_getAttributes should be $entry, as it is in lines 8 and 9. The output from this script is as follows:


Server: example_2.com

------Error Trace------------
ERROR:  Missing or Wrong Parameter: Array parameter "example_2.com" is not a token
Line: 1641, function: XML_PullParser_getAttributes
Error Number: 5  (XML_PullParser_ERROR_BAD_PARAM)

-----End Trace:-------------

We can see what has happened. The third parameter, which should be a tokenized array, is the string "example_2.com". This is the server address from the second server element--which is what is printed by $echo in line 10:

Server:  example_2.com

It's important to remember that when testing for False, it is necessary to use "===" and not "==". The latter will test as true for empty arrays, empty strings and Null , as well as for False. XML_PullParser routinely returns empty arrays, empty strings and Null when no data is available or data has been exhausted. They are not indicators of an Error.


User Defined Errors
For the sake of illustration, let's add a user defined error at line 18 of Listing 22 .


17.    elseif($attr_array === FALSE) {
18.        $err = XML_PullParser_Errors_userDefined("Bad Attributes array");
19.        echo XML_PullParser_Errors_getUserDefined($err) . "\n";
20.        echo XML_PullParser_Errors_Trace() . "\n";
21.        exit;
22.    }    

The result would now look as follows:


User defined error: Bad Attributes array
Line: 18, Top Level

------Error Trace------------
ERROR:  User defined error: Bad Attributes array
Line: 26, Top Level
Error Number: 7  (XML_PullParser_ERROR_USER_DEFINED)

ERROR:  Missing or Wrong Parameter: Array parameter "example_2.com" is not a token
Line: 1641, function: XML_PullParser_getAttributes
Error Number: 5  (XML_PullParser_ERROR_BAD_PARAM)

-----End Trace:-------------

The error message indicates the line number 2 in the user script at which the error was reported, as well as the error message. It also reports that the error occurred at the Top Level . Had this error occurred in a function, then the function would be reported in this place, just as it is in the error reported by XML_PullParser :

Line: 1641, function: XML_PullParser_getAttributes

Finally, we see that the user defined error message is included in the trace. It is reported first in the trace, because it is the most recent error.

Notes
1. The one exception to this is XML_PullParser_pushbackToken.
2. The line number, which here is 18, would of course be the actual line number in the user script.