Moving error handling stuff into Loader and Functions
authorRobert Sesek <rsesek@bluestatic.org>
Thu, 17 Aug 2006 02:56:12 +0000 (02:56 +0000)
committerRobert Sesek <rsesek@bluestatic.org>
Thu, 17 Aug 2006 02:56:12 +0000 (02:56 +0000)
Functions.php
Loader.php

index a6f9b4252ffcf607104eed49ac68ee20f0e85c00..3128797c36353d67ce46cb8be82ab729f36cadcb 100644 (file)
@@ -647,6 +647,44 @@ class BSFunctions
                }
                return $array;
        }
+       
+       // ###################################################################
+       /**
+       * Prepares a debug_backtrace() array for output to the browser by
+       * compressing the array into visible text. This still has value because
+       * debug_print_backtrace() can't return data
+       *
+       * @param        array   debug_backtrace() array
+       *
+       * @return       array   Formatted trace output
+       */
+       public static function FormatDebugTrace($backtrace)
+       {
+               $trace = array();
+               foreach ($backtrace AS $i => $step)
+               {
+                       $args = '';
+                       $file = $step['file'] . ':' . $step['line'];
+                       $funct = (isset($step['class']) ? $step['class'] . '::' . $step['function'] : $step['function']);
+                       
+                       if (isset($step['args']) AND is_array($step['args']))
+                       {
+                               // we need to do this so we don't get "Array to string conversion" notices
+                               foreach ($step['args'] AS $id => $arg)
+                               {
+                                       if (is_array($arg))
+                                       {
+                                               $step['args']["$id"] = 'Array';
+                                       }
+                               }
+                               $args = implode(', ', $step['args']);
+                       }
+       
+                       $trace[] = "#$i  $funct($args) called at [$file]"; 
+               }
+               
+               return $trace;
+       }
 }
 
 /*=====================================================================*\
index 1f17959fed26696b394f3aac70c38e2563ad808a..242fa30f1fc41035890a9b9216fe6df762733655 100644 (file)
@@ -74,6 +74,7 @@ class BSLoader
                if (!self::$instance)
                {
                        self::$instance = new BSLoader;
+                       set_error_handler(array(self::$instance, '_error_handler'));
                }
                return self::$instance;
        }
@@ -174,6 +175,174 @@ class BSLoader
                
                return new $class;
        }
+       
+       // ###################################################################
+       /**
+       * Prints an ISSO message
+       *
+       * @param        string  The title of the message
+       * @param        string  The content of the message
+       * @param        integer Type of message to be printed
+       * @param        bool    Return the output?
+       * @param        bool    Show the debug stack?
+       * @param        integer Message width
+       *
+       * @return       mixed   Output or null
+       */
+       public static function Message($title, $message, $type, $return = false, $stack = true, $width = 500)
+       {
+               switch ($type)
+               {
+                       // Message
+                       case 1:
+                               $prefix = 'Message';
+                               $color = '#669900';
+                               $font = '#000000';
+                       break;
+                       
+                       // Warning
+                       case 2:
+                               $prefix = 'Warning';
+                               $color = '#003399';
+                               $font = '#FFFFFF';
+                       break;
+                       
+                       case 3:
+                               $prefix = 'Error';
+                               $color = '#990000';
+                               $font = '#EFEFEF';
+                       break;
+               }
+               
+               $backtrace = debug_backtrace();
+               array_shift($backtrace);
+               
+               if (isset($backtrace[0]) AND $backtrace[0]['function'] == '_error_handler')
+               {
+                       array_shift($backtrace);
+               }
+               
+               $trace = BSFunctions::FormatDebugTrace($backtrace);
+       
+               $output = "\n<br />\n<table cellpadding=\"4\" cellspacing=\"1\" border=\"0\" width=\"$width\" style=\"background-color: $color; color: black; font-family: Verdana, sans-serif; font-size: 12px;\">";
+               $output .= "\n<tr style=\"color: $font; text-align: left\">\n\t<td><strong>$prefix: $title</strong></td>\n</tr>";
+               $output .= "\n<tr style=\"background-color: #FFFFFF; text-align: left\">\n\t<td>$message</td>\n</tr>";
+               $output .= (($stack AND self::GetRegister()->getDebug()) ? "\n<tr style=\"background-color: #FFFFFF; text-align: left\">\n\t<td><strong>Debug Stack:</strong> <pre>" . implode("\n", $trace) . "</pre></td>\n</tr>" : '');
+               $output .= "\n</table>\n<br />\n";
+               
+               if ($return)
+               {
+                       return $output;
+               }
+               else
+               {
+                       print($output);
+               }
+       }
+       
+       // ###################################################################
+       /**
+       * Custom error handler for ISSO; only handle E_WARNING, E_NOTICE,
+       * E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE
+       *
+       * @param        integer Error number
+       * @param        string  Error message string
+       * @param        string  File that contains the error
+       * @param        string  The line number of the error
+       * @param        string  The active symbol table at which point the error occurred
+       */
+       private function _error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+       {
+               $level = ini_get('error_reporting');
+               
+               switch ($errno)
+               {
+                       // So we don't need to specify the error type in trigger_error(), all E_USER_NOTICEs
+                       // are fatal and automatically kill the script
+                       case E_USER_NOTICE:
+                               $title = 'Fatal';
+                               $mode = 3;
+                       break;
+                       
+                       // A non-fatal but important warning
+                       case E_WARNING:
+                               $title = 'Warning';
+                               $mode = 2;
+                               if (!($level & E_WARNING))
+                               {
+                                       return;
+                               }
+                       break;
+                       
+                       // A non-fatal notice that should all but be ignored unless in dev environments
+                       case E_NOTICE:
+                       case E_STRICT:
+                               $title = 'Notice';
+                               $mode = 1;
+                               if (!($level & E_NOTICE))
+                               {
+                                       return;
+                               }
+                       break;
+                       
+                       case E_USER_WARNING:
+                       case E_USER_NOTICE:
+                       default:
+                               trigger_error('The only error types supported are E_USER_NOTICE (fatal), E_WARNING, and E_NOTICE ' . $errno);
+                       break;
+               }
+               
+               $errstr .= " in <strong>$errfile</strong> on line <strong>$errline</strong>";
+
+               $errstr = str_replace(array(getcwd(), dirname(getcwd())), '', $errstr);
+               
+               self::Message($title, $errstr, $mode);
+               
+               if ($errno == E_USER_NOTICE)
+               {
+                       exit;
+               }
+       }
+       
+       // ###################################################################
+       /**
+       * Creates a table that explains the error reporting levels and their
+       * state
+       */
+       public function explain_error_reporting()
+       {
+               $levels = array(
+                       'E_ERROR'                       => E_ERROR,
+                       'E_WARNING'                     => E_WARNING,
+                       'E_PARSE'                       => E_PARSE,
+                       'E_NOTICE'                      => E_NOTICE,
+                       'E_CORE_ERROR'          => E_CORE_ERROR,
+                       'E_CORE_WARNING'        => E_CORE_WARNING,
+                       'E_COMPILE_ERROR'       => E_COMPILE_ERROR,
+                       'E_COMPILE_WARNING'     => E_COMPILE_WARNING,
+                       'E_USER_ERROR'          => E_USER_ERROR,
+                       'E_USER_WARNING'        => E_USER_WARNING,
+                       'E_USER_NOTICE'         => E_USER_NOTICE,
+                       'E_ALL'                         => E_ALL,
+                       'E_STRICT'                      => E_STRICT
+               );
+               
+               $table = '<table cellspacing="0" cellpadding="2" border="0">';
+               
+               foreach ($levels AS $name => $value)
+               {
+                       $table .= '
+                       <tr>
+                               <td>' . $name . '</td>
+                               <td>' . (ini_get('error_reporting') & $value) . '</td>
+                       </tr>';
+               }
+               
+               $table .= '
+               </table>';
+               
+               $this->message('Error Reporting', $table, 1);
+       }
 }
 
 /*=====================================================================*\