Hot Koehls

The more you know, the more you don’t know

This content is a little crusty, having been with me through 3 separate platform changes. Formatting may be rough, and I am slightly less stupid today than when I wrote it.
12 May 2009

Translating PHP error constants

I wanted to log all the errors thrown out by Fwd:Vault processes to ensure that any bugs I don’t catch myself bubble to the top very quickly. To get started, I replaced PHP’s default error handling with a custom error handler function, which simply logs the error in a MySQL table before passing it along to the normal internal error handler. Later, I’m going to add non-error notices to the mix, and set up an RSS feed to output these errors, allowing me real-time updates on overall system health. If the error handling stuff sounds like Greek, read up before going further:

  • PHP error handling
  • <a href="http://www.php.net/manual/en/function.set-error-handler.php">set_error_handler()</a>
  • <a href="http://www.php.net/manual/en/function.error-reporting.php">error_reporting()</a>
  • <a href="http://www.php.net/manual/en/function.trigger-error.php">trigger_error()</a>

When PHP throws any kind of error, the error is assigned an error level, which can be expressed in two ways: an integer or a predefined constant. The constant represents the integer, making the two completely interchangeable. However if you build a custom error handler, you are only given the integer, which doesn’t automagically translate back to the constant value. It’s a heckuva lot easier to recognize E_USER_ERROR instead of the integer 256, so I want to store that error constant for reading purposes. If you find yourself looking at error numbers, and want the matching constant string, use this block of code:

switch ($errno) {

  case 1:     $e_type = 'E_ERROR'; break;

  case 2:     $e_type = 'E_WARNING'; break;

  case 4:     $e_type = 'E_PARSE'; break;

  case 8:     $e_type = 'E_NOTICE'; break;

  case 16:    $e_type = 'E_CORE_ERROR'; break;

  case 32:    $e_type = 'E_CORE_WARNING'; break;

  case 64:    $e_type = 'E_COMPILE_ERROR'; break;

  case 128:   $e_type = 'E_COMPILE_WARNING'; break;

  case 256:   $e_type = 'E_USER_ERROR'; break;

  case 512:   $e_type = 'E_USER_WARNING'; break;

  case 1024:  $e_type = 'E_USER_NOTICE'; break;

  case 2048:  $e_type = 'E_STRICT'; break;

  case 4096:  $e_type = 'E_RECOVERABLE_ERROR'; break;

  case 8192:  $e_type = 'E_DEPRECATED'; break;

  case 16384: $e_type = 'E_USER_DEPRECATED'; break;

  case 30719: $e_type = 'E_ALL'; break;

  default:    $e_type = 'E_UNKNOWN'; break;

}

```

This will give you a string in `$e_type` matching the proper constants. The `switch` block accounts for all the current PHP constants as of this posting, plus a catch-all `E_UNKNOWN` in case you're doing something **really** weird.
Now let's add some perspective to this code block. Here's an sample custom error handler that grabs the constant string for logging purposes and outputs the error to the screen. The internal handler is bypassed in this example, since we don't need it to do anything (note how the function kills page processing when a fatal error occurs). We'll also set this custom function as the default error handler.
function custom_error_handler($errno, $errstr, $errfile, $errline) {

  $exit_now = false;

  switch ($errno) {

    case 1:     $e_type = 'E_ERROR'; $exit_now = true; break;

    case 2:     $e_type = 'E_WARNING'; break;

    case 4:     $e_type = 'E_PARSE'; break;

    case 8:     $e_type = 'E_NOTICE'; break;

    case 16:    $e_type = 'E_CORE_ERROR'; $exit_now = true; break;

    case 32:    $e_type = 'E_CORE_WARNING'; break;

    case 64:    $e_type = 'E_COMPILE_ERROR'; $exit_now = true; break;

    case 128:   $e_type = 'E_COMPILE_WARNING'; break;

    case 256:   $e_type = 'E_USER_ERROR'; $exit_now = true; break;

    case 512:   $e_type = 'E_USER_WARNING'; break;

    case 1024:  $e_type = 'E_USER_NOTICE'; break;

    case 2048:  $e_type = 'E_STRICT'; break;

    case 4096:  $e_type = 'E_RECOVERABLE_ERROR'; $exit_now = true; break;

    case 8192:  $e_type = 'E_DEPRECATED'; break;

    case 16384: $e_type = 'E_USER_DEPRECATED'; break;

    case 30719: $e_type = 'E_ALL'; $exit_now = true; break;

    default:    $e_type = 'E_UNKNOWN'; break;

  }

  echo "**$e_type** — $errstr on line $errline in file $errfile
n";

  //send_to_log("$e_type - $errstr on line $errline in file $errfile");

  if ($exit_now) exit(1);

  // Don't execute PHP internal error handler

  return true;

}

set_error_handler('custom_error_handler');

```

At this point you have all the information necessary to do whatever you want with the error. A future post will expand on that `send_to_log()` statement, but serves as a placeholder example.

      

comments powered by Disqus