I'm running into an issue where my PHP project is not catching exceptions when I use a Try Catch Block. When an exception is thrown PHP will still display the exception's error message and will end execution of the PHP script. I have narrowed it down to the fact that I have a custom PHP error handler I built. Once I remove my custom PHP handler then TRY CATCH blocks work normally again. Removing the custom error handler is not an option unfortunately. Please see code below:
use \ErrorException;
use \BrowserDetection;
use \DateTime;
use \DateTimeZone;
use \Database;
define("DEBUG_ON", "DEBUG_ON");
define("DEBUG_OFF", "DEBUG_OFF");
ErrorHandler::register();
class ErrorHandler
{
public static function register() {
global $_WEBCONFIG;
if(!isset($_COOKIE['XDEBUG_SESSION'])) {
if($_WEBCONFIG['DEBUG_SETTING'] == DEBUG_OFF || stristr($_SERVER['PHP_SELF'], 'error.php')) {
ini_set('display_errors', '0');
error_reporting(0);
} else {
ini_set('display_errors', '1');
switch ($_WEBCONFIG['DEBUG_WARNING_LEVEL']) {
case 1:
error_reporting(E_ERROR | E_PARSE);
set_error_handler(array("Base\Handlers\ErrorHandler", "error_handler"), E_ERROR | E_PARSE);
break;
case 2:
error_reporting(E_ERROR | E_WARNING | E_PARSE);
set_error_handler(array("Base\Handlers\ErrorHandler", "error_handler"), E_ERROR | E_WARNING | E_PARSE);
break;
case 3:
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
set_error_handler(array("Base\Handlers\ErrorHandler", "error_handler"), E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
break;
case 4:
error_reporting(E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
set_error_handler(array("Base\Handlers\ErrorHandler", "error_handler"), E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
break;
default:
error_reporting(E_ALL);
set_error_handler(array("Base\Handlers\ErrorHandler", "error_handler"), E_ALL);
register_shutdown_function(array("Base\Handlers\ErrorHandler", "fatal_error_handler"));
}
set_exception_handler(array("Base\Handlers\ErrorHandler", "exception_handler"));
}
}
}
public static function log_exception($exception) {
require_once($_SERVER['DOCUMENT_ROOT'] . "/library/classes/class_browser_detection.php");
global $_WEBCONFIG, $siteConfig;
$browser = new BrowserDetection();
$userBrowserName = $browser->getBrowser();
$userBrowserVer = $browser->getVersion();
$userBrowserPlatform = $browser->getPlatform();
$userBrowserIsMobile = $browser->isMobile() == "" ? "No" : "Yes";
$userBrowserIsRobot = $browser->isRobot() == "" ? "No" : "Yes";
$companyName = isset($siteConfig['Company_Name']) ? $siteConfig['Company_Name'] : '';
$userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Unknown';
$ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : 'N/A';
$today = new DateTime("now", new DateTimeZone('US/Central'));
$date = $today->format("F j, Y g:i a");
$username = isset($_SESSION['member_username']) ? $_SESSION['member_username'] : (isset($_SESSION['user_username']) ? $_SESSION['user_username'] : null);
// Remove ErrorException Trace Referenceing Error Handler & Get Error Type
if(get_class($exception) == "Base\Handlers\CoreErrorException") {
$sTraceArray = array_slice(explode("\n", $exception->getTraceAsString()), 1);
$traceString = implode($sTraceArray);
$type = $exception->getExceptionType();
} else {
$traceString = $exception->getTraceAsString();
$type = 'E_' . strtoupper(get_class($exception));
}
$message = '<p><b>EXCEPTION TYPE</b>: ' . $type . PHP_EOL;
$message .= '<br /><b>MESSAGE: </b>' . $exception->getMessage(). PHP_EOL;
$message .= '<br /><b>SITE PAGE: </b>' . $_SERVER['ABSOLUTE_URI']. PHP_EOL;
$message .= '<br /><b>LOCATION: </b>' . $exception->getFile(). PHP_EOL;
$message .= '<br /><b>LINE NUMBER: </b>' . $exception->getLine(). PHP_EOL;
if(!is_null($username)) {
$message .= '<br /><b>USERNAME: </b>' . $username . PHP_EOL;
}
$message .= '<br /><b>USER AGENT: </b>' . $userAgent . PHP_EOL;
$message .= '<br /><b>OPERATING SYSTEM: </b>' . $userBrowserPlatform . PHP_EOL;
$message .= '<br /><b>BROWSER: </b>' . $userBrowserName . ' ' . $userBrowserVer . PHP_EOL;
$message .= '<br /><b>MOBILE: </b>' . $userBrowserIsMobile . PHP_EOL;
$message .= '<br /><b>ROBOT: </b>' . $userBrowserIsRobot . PHP_EOL;
$message .= '<br /><b>IP ADDRESS: </b>' . $ip . PHP_EOL;
$message .= '<br /><b>ERROR TIME: </b>' . $date . "\n</p>" . PHP_EOL;;
$message .= '<p><b>' . str_repeat("-", 75) . ' PHP STACK TRACE ' . str_repeat("-", 75) . '</b>' . PHP_EOL;
$message .= str_replace('#', '<br />#', $traceString) . "</p>\n". PHP_EOL;;
if(Database::hasConnection()) {
$trace = Database::quote_smart($traceString);
$filepath = Database::quote_smart($exception->getFile());
$errLine = (int) $exception->getLine();
$errNo = (int) $exception->getCode();
$errStr = Database::quote_smart($exception->getMessage());
if(!is_null($username)) {
if(isset($_SESSION['member_prov_num'])) {
$providerNo = $_SESSION['member_prov_num'];
$sql = "INSERT INTO `tbl_error_log` (`el_type`, `el_code`, `el_message`, `el_url`, `el_file_path`, `el_line_number`, `el_user_agent`, `el_ip_address`, `el_details`, `el_username`, `el_provider_number`)
VALUES ('$type', '$errNo', '$errStr', '{$_SERVER['ABSOLUTE_URI']}', '$filepath', '$errLine', '$userAgent', '$ip', '$trace', '$username', '$providerNo');";
} else {
$sql = "INSERT INTO `tbl_error_log` (`el_type`, `el_code`, `el_message`, `el_url`, `el_file_path`, `el_line_number`, `el_user_agent`, `el_ip_address`, `el_details`, `el_username`)
VALUES ('$type', '$errNo', '$errStr', '{$_SERVER['ABSOLUTE_URI']}', '$filepath', '$errLine', '$userAgent', '$ip', '$trace', '$username');";
}
} else {
$sql = "INSERT INTO `tbl_error_log` (`el_type`, `el_code`, `el_message`, `el_url`, `el_file_path`, `el_line_number`, `el_user_agent`, `el_ip_address`, `el_details`)
VALUES ('$type', '$errNo', '$errStr', '{$_SERVER['ABSOLUTE_URI']}', '$filepath', '$errLine', '$userAgent', '$ip', '$trace');";
}
Database::ExecuteRaw($sql);
}
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: ' . $companyName .' <[email protected]>' . "\r\n";
if($_WEBCONFIG['DEBUG_SETTING'] == DEBUG_ON) {
$recipients = str_replace(";",",",$_WEBCONFIG['DEVELOPER_EMAIL']);
mail($recipients, 'Error Message', $message, $headers);
}
return $message;
}
public static function error_handler($errNo, $errStr, $errFile, $errLine)
{
// Convert PHP Error Into Exception
self::exception_handler(new CoreErrorException($errStr, $errNo, $errFile, $errLine));
}
public static function fatal_error_handler() {
$last_error = error_get_last();
if(isset($last_error['type'])
|| $last_error['type'] === E_ERROR
|| $last_error['type'] === E_CORE_ERROR
|| $last_error['type'] === E_CORE_WARNING
|| $last_error['type'] === E_COMPILE_ERROR
|| $last_error['type'] === E_COMPILE_WARNING) {
self::exception_handler(new CoreErrorException($last_error['message'], $last_error['type'], $last_error['file'], $last_error['line']));
}
}
public static function exception_handler($exception) {
global $_WEBCONFIG;
$message = self::log_exception($exception);
if($_WEBCONFIG['FRIENDLY_ERRORS'] == "Off" || ($_WEBCONFIG['FRIENDLY_ERRORS'] == "Local" && ($ip == $_WEBCONFIG["LOCAL_IP"] || '127.0.0.1'))) {
header_remove('content-type');
header('content-type: text/html; charset=UTF-8');
if (ob_get_length() > 0) { ob_end_clean(); }
self::print_header();
print $message;
self::print_footer();
exit();
} else {
$errorPage = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
redirect($_WEBCONFIG['CUSTOMERRORS']['DEFAULTREDIRECT']['500'] . '?path=' . $errorPage);
}
}
private static function print_header() {
global $_WEBCONFIG, $siteConfig;
print '<!doctype html><html xmlns="http://www.w3.org/1999/xhtml"><head><title>PHP Page Error</title>';
print '<style>body { background-color: #fcfcfc; color: #333333; margin: 0; padding:0; } h1 { font-size: 1.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; } h1, p { padding-left: 10px; } code.url { background-color: #eeeeee; font-family:monospace; padding:0 2px;}</style>';
print '</head><body>';
print '<div class="content" style="left: 50px;">';
print "<h1>PHP Page Error</h1>";
}
private static function print_footer() {
print '</div></body></html>';
}
}
class CoreErrorException extends ErrorException {
protected $errorType;
public function __construct($errStr, $errNo, $errFile, $errLine) {
parent::__construct($errStr, 0, $errNo, $errFile, $errLine);
switch ($this->code) {
case E_ERROR:
$this->errorType = "E_ERROR";
break;
case E_WARNING :
$this->errorType = "E_WARNING";
break;
case E_PARSE :
$this->errorType = "E_PARSE";
break;
case E_NOTICE:
$this->errorType = "E_NOTICE";
break;
case E_CORE_ERROR :
$this->errorType = "E_CORE_ERROR";
break;
case E_CORE_WARNING :
$this->errorType = "E_CORE_WARNING";
break;
case E_COMPILE_ERROR:
$this->errorType = "E_COMPILE_ERROR";
break;
case E_COMPILE_WARNING :
$this->errorType = "E_COMPILE_WARNING";
break;
case E_USER_ERROR :
$this->errorType = "E_USER_ERROR";
break;
case E_USER_WARNING:
$this->errorType = "E_USER_WARNING";
break;
case E_USER_NOTICE :
$this->errorType = "E_USER_NOTICE";
break;
case E_STRICT :
$this->errorType = "E_STRICT";
break;
case E_RECOVERABLE_ERROR:
$this->errorType = "E_RECOVERABLE_ERROR";
break;
case E_DEPRECATED :
$this->errorType = "E_DEPRECATED";
break;
case E_USER_DEPRECATED :
$this->errorType = "E_USER_DEPRECATED";
break;
default:
$this->errorType = "E_CORE";
}
}
public function getExceptionType() {
return $this->errorType . '_EXCEPTION';
}
}
?>
I have also included an example of a catch block where the code is not being caught:
try {
$response = $client->GetAllOrdersByOrderNo($request);
} catch (Exception $e) {
$response = null;
}
Class Calling Exception
<?php
namespace Base\Members\Library;
use \SoapClient;
use \SimpleXMLElement;
class MembershipAPI
{
public static function getOrderByOrderNo($orderNo) {
$client = new SoapClient("https://bah.foo.com/members/Services/Orders.svc?wsdl");
$request = array(array());
$request['request']['OrderNo'] = $orderNo;
try {
$response = $client->GetAllOrdersByOrderNo($request);
} catch (Exception $e) {
// This code is never set
$response = null;
}
/*if (response.OperationStatus != Orders.ExternalServiceResponseStatus.Success)
{
throw new Exception(response.OperationErrors[0]);
} */
return isset($response->GetAllOrdersByOrderNoResult->Orders->Order) ? $response->GetAllOrdersByOrderNoResult->Orders->Order : null;
}
}
GetAllOrdersByOrderNoimplementation that is throwing the new Exception (throw new Exception("some error"))? and does the Class it's throwing implement\Exceptionas it is not required in PHP so you can't catch an exception if it's not child class of\Exceptionwithcatch(\Excpetion $e).$client->GetAllOrdersByOrderNo($request);will never throw an exception even if the remote system throws an exception it should output the exception or error to you, you then have to parse the result to check if it's in error state. also to note PHP Programming errors are not exceptions in PHP they are errors, Can you provide a demo of a failed state responseecho "<pre>".print_r($response, true)."</pre>";