-
-
Save ircmaxell/ef12f5779c32cd02b9e8 to your computer and use it in GitHub Desktop.
ErrorExceptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use ErrorExceptions\ErrorExceptions; | |
class ConfigurationException extends LogicException {} | |
class DisabledFeatureException extends ConfigurationException {} | |
class OpenBaseDirException extends DisabledFeatureException {} | |
class SafeModeException extends DisabledFeatureException {} | |
class URLFileAccessDisabledException extends ConfigurationException {} | |
ErrorExceptions::addMultipleCoreExceptions(array( | |
E_WARNING => array( | |
'/function is disabled/' => 'DisabledFeatureException', | |
'/has been disabled for security reasons/' => '', | |
'/open(_|\s)basedir/i' => 'OpenBaseDirException', | |
'/safe(_|\s)mode/i' => 'SafeModeException', | |
'/Unable to access .*/' => 'SafeModeException', | |
), | |
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use ErrorExceptions\ErrorExceptions; | |
class ConflictException extends LogicException {} | |
class DeprecatedException extends LogicException {} | |
class InvalidCallbackException extends LogicException {} | |
class InvalidClassException extends LogicException {} | |
class InvalidImplementationException extends LogicException {} | |
class InvalidInputException extends RuntimeException {} | |
class InvalidReturnValueException extends LogicException {} | |
class InvalidScopeException extends LogicException {} | |
class InvalidValueException extends LogicException {} | |
class OutOfMemoryException extends RuntimeException {} | |
class NotSupportedException extends RuntimeException {} | |
class OutputException extends RuntimeException {} | |
class ParseException extends LogicException {} | |
class PHPCoreException extends LogicException {} | |
class ReferenceException extends LogicException {} | |
class StrictException extends LogicException {} | |
class TypeConversionException extends LogicException {} | |
class UndefinedConstantException extends LogicException {} | |
class UndefinedVariableException extends LogicException {} | |
class UnknownErrorException extends RuntimeException {} | |
class WTFException extends LogicException {} | |
ErrorExceptions::addMultipleCoreExceptions(array( | |
E_DEPRECATED => array( | |
'/./' => 'DeprecatedException', | |
), | |
E_NOTICE => array( | |
'/Constant .* already defined/' => 'LogicException', | |
'/Exceptions must be derived from the Exception/' => 'InvalidClassException', | |
'/failed to (flush|delete|delete and flush) buffer/' => 'OutputException', | |
'/(modify|assign|get) property of non-object/' => 'LogicException', | |
'/(Illegal|Corrupt) member variable name/' => 'ParseException', | |
'/Indirect modification of overloaded property/' => 'LogicException', | |
'/(Object|Array) .* to string conversion/' => 'TypeConversionException', | |
'/Object of class .* could not be converted to/' => 'TypeConversionException', | |
'/undefined constant/i' => 'UndefinedConstantException', | |
'/undefined (property|variable)/i' => 'UndefinedVariableException', | |
'/Undefined offset/' => 'OutOfBoundsException', | |
'/Uninitialized string offset/' => 'OutOfBoundsException', | |
), | |
E_RECOVERABLE_ERROR => array( | |
'/__toString\(\) must return a string/' => 'InvalidReturnValueException', | |
'/Argument \d+ passed to .* must/' => 'InvalidArgumentException', | |
'/Cannot get arguments for calling closure/' => 'LogicException', | |
'/Closure object cannot have properties/' => 'LogicException', | |
'/Instantiation of .* is not allowed/' => 'LogicException', | |
'/Object of class .* could not be converted to/' => 'TypeConversionException', | |
), | |
E_STRICT => array( | |
'/Accessing static property .* as non static/' => 'StrictException', | |
'/Creating default object from empty value/' => 'UndefinedVariableException', | |
'/Non-static method .* be called statically/' => 'StrictException', | |
'/Redefining already defined constructor/' => 'ParseException', | |
'/Resource .* used as offset/' => 'TypeConversionException', | |
'/Static function .* should not be abstract/' => 'ParseException', | |
), | |
E_WARNING => array( | |
'/__toString\(\) must return a string/' => 'InvalidReturnValueException', | |
'/a COM object/i' => 'com_exception', | |
'/Argument \d+ not passed to function/' => 'OutOfBoundsException', | |
'/bad type specified while parsing parameters/' => 'PHPCoreException', | |
'/called from outside a class/' => 'InvalidScopeException', | |
'/Can only handle single dimension variant arrays/' => 'com_exception', | |
'/Cannot add element to the array/' => 'RuntimeException', | |
'/Cannot add (user|internal) functions to return value/' => 'PHPCoreException', | |
'/Cannot convert to (real|ordinal) value/' => 'TypeConversionException', | |
'/Cannot (read|write) property of object - .* handler defined/' => 'PHPCoreException', | |
'/Cannot redeclare class/' => 'InvalidClassException', | |
'/Cannot unset offset in a non-array variable/' => 'LogicException', | |
'/Cannot use a scalar value as an array/' => 'TypeConversionException', | |
'/class .* is undefined/' => 'InvalidClassException', | |
'/Class .* not found/' => 'InvalidClassException', | |
'/Class constants cannot be defined/' => 'LogicException', | |
'/Clone method does not require arguments/' => 'ParseException', | |
'/Constants may only evaluate to scalar values/' => 'InvalidValueException', | |
'/converting from PHP array to VARIANT/' => 'TypeConversionException', | |
'/Could not convert string to unicode/i' => 'InvalidInputException', | |
'/Could not execute/' => 'LogicException', | |
'/Could not find a factory/' => 'PHPCoreException', | |
'/could not obtain parameters for parsing/' => 'PHPCoreException', | |
'/expected to be a reference/' => 'ReferenceException', | |
'/expects the argument .* to be a valid callback/' => 'InvalidCallbackException', | |
'/expects parameter \d+ to be a valid callback/' => 'InvalidCallbackException', | |
'/failed allocating/i' => 'OutOfMemoryException', | |
'/failed to allocate/i' => 'OutOfMemoryException', | |
'/first parameter has to be/i' => 'InvalidArgumentException', | |
'/First parameter must either be/' => 'InvalidArgumentException', | |
'/function is not supported/' => 'BadFunctionCallException', | |
'/handler .* did not return a/' => 'LogicException', | |
'/Illegal offset type/' => 'LogicException', | |
'/Illegal string offset/' => 'OutOfBoundsException', | |
'/Illegal type returned from/' => 'InvalidReturnValueException', | |
'/Indirect modification of overloaded element/' => 'LogicException', | |
'/Input variable nesting level exceeded/' => 'InvalidInputException', | |
'/invalid .* ID/i' => 'InvalidArgumentException', | |
'/Invalid callback/' => 'InvalidCallbackException', | |
'/invalid date/' => 'InvalidArgumentException', | |
'/Invalid error type specified/' => 'DomainException', | |
'/Illegal offset type/' => 'DomainException', | |
'/invalid parameter given for/i' => 'DomainException', | |
'/Invalid scanner mode/' => 'DomainException', | |
'/is no longer supported/' => 'DeprecatedException', | |
'/is not a valid mode for/' => 'DomainException', | |
'/is not a valid .* resource/' => 'DomainException', | |
'/is not implemented/' => 'InvalidImplementationException', | |
'/is only valid for years between/i' => 'OutOfRangeException', | |
'/is too long for/' => 'DomainException', | |
'/may not be negative/i' => 'OutOfRangeException', | |
'/(modify|assign|get) property of non-object/' => 'LogicException', | |
'/must be a name of .* class/' => 'InvalidClassException', | |
'/must be greather than/' => 'RangeException', | |
'/must not return itself/' => 'InvalidReturnValueException', | |
'/must return a/' => 'InvalidReturnValueException', | |
'/no .* resource supplied/' => 'InvalidArgumentException', | |
'/no function context/' => 'LogicException', | |
'/not a dispatchable interface/' => 'BadMethodCallException', | |
'/not supported on this platform/' => 'NotSupportedException', | |
'/Nothing returned from/' => 'InvalidReturnValueException', | |
'/object doesn\'t support property references/' => 'ReferenceException', | |
'/only one varargs specifier/' => 'PHPCoreException', | |
'/output handler .* conflicts with/' => 'ConflictException', | |
'/Parameter wasn\'t passed by reference/' => 'ReferenceException', | |
'/POST Content-Length of/' => 'InvalidInputException', | |
'/POST length does not match Content-Length/' => 'InvalidInputException', | |
'/request_startup.* failed/' => 'PHPCoreException', | |
'/should be >/' => 'RangeException', | |
'/The magic method .* must have public/' => 'ParseException', | |
'/The use statement with non-compound name/' => 'ParseException', | |
'/this code not yet written/i' => 'WTFException', | |
'/timestamp value must be a positive value/i' => 'InvalidArgumentException', | |
'/type library constant .* already defined/i' => 'LogicException', | |
'/Unable to find typeinfo using/i' => 'RuntimeException', | |
'/Unknown .* list entry type in/' => 'PHPCoreException', | |
'/Unspecified error/' => 'UnknownErrorException', | |
'/Variable passed to .* is not an/' => 'DomainException', | |
'/variant is not an/' => 'InvalidArgumentException', | |
'/variant: failed to copy from/' => 'TypeConversionException', | |
'/Wrong parameter count for/' => 'InvalidArgumentException', | |
'/year out of range/i' => 'OutOfRangeException', | |
'/zval: conversion from/' => 'TypeConversionException', | |
), | |
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace ErrorExceptions; | |
use ErrorException; | |
require_once 'ConfigurationExceptions.php'; | |
require_once 'CoreExceptions.php'; | |
require_once 'IOExceptions.php'; | |
require_once 'MathExceptions.php'; | |
class ErrorExceptions { | |
protected $callbacks = array(); | |
protected $errors = E_ALL; | |
protected static $coreExceptions = array(); | |
protected $exceptions = array(); | |
protected $failureCallbacks = array(); | |
protected $lastError = array(); | |
protected $registered = false; | |
public static function addMultipleCoreExceptions(array $exceptions) { | |
static::$coreExceptions = array_merge_recursive_correct( | |
$exceptions, static::$coreExceptions | |
); | |
} | |
public function __construct($errorLevel = E_ALL) { | |
$this->errors = $errorLevel; | |
$this->exceptions = static::$coreExceptions; | |
} | |
public function addCallback($callback) { | |
if (is_callable($callback)) { | |
$this->callbacks[] = $callback; | |
} | |
} | |
public function addFailureCallback($callback) { | |
if (is_callable($callback)) { | |
$this->failureCallbacks[] = $callback; | |
} | |
} | |
public function addException($errNo, $regex, $exception) { | |
if (!isset($this->exceptions[$errNo])) { | |
$this->exceptions[$errNo] = array(); | |
} | |
$this->exceptions[$errNo][$regex] = $exception; | |
} | |
public function addMultipleExceptions(array $exceptions) { | |
$this->exceptions = array_merge_recursive_correct( | |
$exceptions, $this->exceptions | |
); | |
} | |
public function handleError($errNo, $errStr, $errFile, $errLine) { | |
if (!$this->registered) { | |
return true; | |
} | |
$this->lastError = array( | |
'type' => $errNo, | |
'message' => $errStr, | |
'file' => $errFile, | |
'line' => $errLine | |
); | |
$exception = $this->lookupError($errNo, $errStr, $errFile, $errLine); | |
if ($exception && class_exists($exception)) { | |
$previous = new ErrorException( | |
$errStr, | |
0, | |
$errNo, | |
$errFile, | |
$errLine | |
); | |
throw new $exception($errStr, $errNo, $previous); | |
} | |
return $exception; | |
} | |
public function handleShutdown() { | |
if (!$this->registered) { | |
return true; | |
} | |
$error = error_get_last(); | |
if (!is_null($error) && $error != $this->lastError) { | |
$this->callFailedCallbacks( | |
$error['type'], $error['message'], $error['file'], $error['line'] | |
); | |
} | |
} | |
public function register() { | |
set_error_handler( | |
array($this, 'handleError'), $this->errors | |
); | |
register_shutdown_function(array($this, 'handleShutdown')); | |
$this->registered = true; | |
} | |
public function unregister() { | |
restore_error_handler(); | |
$this->registered = false; | |
} | |
protected function callFailedCallbacks($errNo, $errStr, $errFile, $errLine) { | |
foreach ($this->failureCallbacks as $callback) { | |
if (call_user_func($callback, $errNo, $errStr, $errFile, $errLine)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
protected function lookupError($errNo, $errStr, $errFile, $errLine) { | |
foreach ($this->callbacks as $callback) { | |
$exception = call_user_func($callback, $errNo, $errStr); | |
if ($exception && class_exists($exception)) { | |
return $exception; | |
} | |
} | |
if (!isset($this->exceptions[$errNo])) { | |
return false; | |
} | |
foreach ($this->exceptions[$errNo] as $regex => $exception) { | |
if (preg_match($regex, $errStr)) { | |
return $exception; | |
} | |
} | |
return $this->callFailedCallbacks($errNo, $errStr, $errFile, $errLine); | |
} | |
} | |
function array_merge_recursive_correct(array $array1, array $array2) { | |
foreach ($array2 as $key => $value) { | |
if (isset($array1[$key]) && is_array($array1[$key]) && is_array($value)) { | |
$array1[$key] = array_merge_recursive_correct($array1[$key], | |
$array2[$key]); | |
} else { | |
$array1[$key] = $value; | |
} | |
} | |
return $array1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use ErrorExceptions\ErrorExceptions; | |
class CurlException extends LogicException {} | |
class DNSException extends IOException {} | |
class FileNotFoundException extends IOException {} | |
class IOException extends RuntimeException {} | |
class InvalidFileNameException extends InvalidPathException {} | |
class InvalidLockException extends IOException {} | |
class InvalidNetworkAddressException extends InvalidPathException {} | |
class InvalidPathException extends IOException {} | |
class InvalidProtocolException extends InvalidURLException {} | |
class InvalidStreamException extends IOException {} | |
class InvalidURLException extends InvalidPathException {} | |
class NotReadableException extends IOException {} | |
class NotWritableException extends IOException {} | |
class PartialWriteException extends WriteFailureException {} | |
class ReadFailureException extends IOException {} | |
class SSLException extends IOException {} | |
class StatException extends IOException {} | |
class StreamFilterException extends IOException {} | |
class StreamWrapperException extends IOException {} | |
class WriteFailureException extends IOException {} | |
ErrorExceptions::addMultipleCoreExceptions(array( | |
E_NOTICE => array( | |
'/:\/\/ was never changed, nothing to restore/' => 'StreamWrapperException', | |
'/path was truncated to/' => 'InvalidPathException', | |
'/send of \d+ bytes failed/' => 'WriteFailureException', | |
), | |
E_WARNING => array( | |
'/:\/\/ never existed, nothing to restore/' => 'StreamWrapperException', | |
'/Attempt to close cURL handle from a callback/' => 'CurlException', | |
'/bytes more data than requested/' => 'OverflowException', | |
'/call the CURL/i' => 'CurlException', | |
'/cannot peek or fetch OOB data/' => 'ReadFailureException', | |
'/cannot read from a stream opened in/' => 'InvalidStreamException', | |
'/cannot seek/' => 'IOException', | |
'/cannot use stream opened in mode/' => 'InvalidStreamException', | |
'/cannot write OOB data/' => 'WriteFailureException', | |
'/Could not build curl_slist/' => 'CurlException', | |
'/could not extract hash key from/' => 'SSLException', | |
'/could not read .* data from stream/' => 'IOException', | |
'/cURL handle/' => 'CurlException', | |
'/CURLOPT/' => 'InvalidArgumentException', | |
'/Failed opening .* for (inclusion|highlighting)/' => 'NotReadableException', | |
'/failed to bind to/' => 'IOException', | |
'/Failed to resolve/' => 'DNSException', | |
'/filename cannot be empty/' => 'InvalidFileNameException', | |
'/file handle is not writable/' => 'NotWritableException', | |
'/File name is longer than the maximum/' => 'InvalidFileNameException', | |
'/getaddrinfo failed/' => 'DNSException', | |
'/gethostbyname failed/' => 'DNSException', | |
'/Invalud curl configuration option/' => 'CurlException', | |
'/Invalid IP address/' => 'InvalidNetworkAddressException', | |
'/invalid URL/' => 'InvalidURLException', | |
'/No such file or directory/' => 'FileNotFoundException', | |
'/protocol .* disabled in curl/i' => 'InvalidProtocolException', | |
'/Protocol .* already defined/' => 'StreamWrapperException', | |
'/There was an error mcode=/' => 'CurlException', | |
'/this stream does not support SSL/' => 'SSLException', | |
'/unable to allocate stream/' => 'IOException', | |
'/Unable to find the wrapper/' => 'StreamWrapperException', | |
'/Unable to include uri/' => 'IOException', | |
'/Unable to include .* (URI|request)/' => 'IOException', | |
'/Unable to register wrapper/' => 'StreamWrapperException', | |
'/Unable to restore original .* wrapper/' => 'StreamWrapperException', | |
'/Unable to unregister protocol/' => 'StreamWrapperException', | |
'/URI lookup failed/' => 'DNSException', | |
), | |
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use ErrorExceptions\ErrorExceptions; | |
class ZeroDivisionException extends MathException {} | |
class MathException extends LogicException {} | |
ErrorExceptions::addMultipleCoreExceptions(array( | |
E_WARNING => array( | |
'/Division by zero/' => 'ZeroDivisionException', | |
'/Square root of a negative number/' => 'MathException', | |
), | |
)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment