mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #3512 from tractorcow/pulls/3.2/exceptions
BUG ErrorControlChain now supports exception handling
This commit is contained in:
commit
b4df2aa80f
@ -17,9 +17,25 @@
|
|||||||
class ErrorControlChain {
|
class ErrorControlChain {
|
||||||
public static $fatal_errors = null; // Initialised after class definition
|
public static $fatal_errors = null; // Initialised after class definition
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is there an error?
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
protected $error = false;
|
protected $error = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of steps
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
protected $steps = array();
|
protected $steps = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if errors should be hidden
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
protected $suppression = true;
|
protected $suppression = true;
|
||||||
|
|
||||||
/** We can't unregister_shutdown_function, so this acts as a flag to enable handling */
|
/** We can't unregister_shutdown_function, so this acts as a flag to enable handling */
|
||||||
@ -28,6 +44,18 @@ class ErrorControlChain {
|
|||||||
/** We overload display_errors to hide errors during execution, so we need to remember the original to restore to */
|
/** We overload display_errors to hide errors during execution, so we need to remember the original to restore to */
|
||||||
protected $originalDisplayErrors = null;
|
protected $originalDisplayErrors = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any exceptions passed through the chain
|
||||||
|
*
|
||||||
|
* @var Exception
|
||||||
|
*/
|
||||||
|
protected $lastException = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if an error has been found
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function hasErrored() {
|
public function hasErrored() {
|
||||||
return $this->error;
|
return $this->error;
|
||||||
}
|
}
|
||||||
@ -57,19 +85,43 @@ class ErrorControlChain {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that the callback is invoked if not errored
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function thenWhileGood($callback) {
|
public function thenWhileGood($callback) {
|
||||||
return $this->then($callback, false);
|
return $this->then($callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that the callback is invoked on error
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function thenIfErrored($callback) {
|
public function thenIfErrored($callback) {
|
||||||
return $this->then($callback, true);
|
return $this->then($callback, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that the callback is invoked always
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function thenAlways($callback) {
|
public function thenAlways($callback) {
|
||||||
return $this->then($callback, null);
|
return $this->then($callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the last error was fatal
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
protected function lastErrorWasFatal() {
|
protected function lastErrorWasFatal() {
|
||||||
|
if($this->lastException) return true;
|
||||||
$error = error_get_last();
|
$error = error_get_last();
|
||||||
return $error && ($error['type'] & self::$fatal_errors) != 0;
|
return $error && ($error['type'] & self::$fatal_errors) != 0;
|
||||||
}
|
}
|
||||||
@ -122,7 +174,12 @@ class ErrorControlChain {
|
|||||||
$step = array_shift($this->steps);
|
$step = array_shift($this->steps);
|
||||||
|
|
||||||
if ($step['onErrorState'] === null || $step['onErrorState'] === $this->error) {
|
if ($step['onErrorState'] === null || $step['onErrorState'] === $this->error) {
|
||||||
call_user_func($step['callback'], $this);
|
try {
|
||||||
|
call_user_func($step['callback'], $this);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$this->lastException = $ex;
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->step();
|
$this->step();
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
* `SS_Filterable`, `SS_Limitable` and `SS_Sortable` now explicitly extend `SS_List`
|
* `SS_Filterable`, `SS_Limitable` and `SS_Sortable` now explicitly extend `SS_List`
|
||||||
* `Convert::html2raw` no longer wraps text by default and can decode single quotes.
|
* `Convert::html2raw` no longer wraps text by default and can decode single quotes.
|
||||||
* `Mailer` no longer calls `xml2raw` on all email subject line, and now must be passed in via plain text.
|
* `Mailer` no longer calls `xml2raw` on all email subject line, and now must be passed in via plain text.
|
||||||
|
* `ErrorControlChain` now supports reload on exceptions
|
||||||
|
|
||||||
#### Deprecated classes/methods removed
|
#### Deprecated classes/methods removed
|
||||||
|
|
||||||
|
@ -140,6 +140,21 @@ class ErrorControlChainTest extends SapphireTest {
|
|||||||
->executeInSubprocess();
|
->executeInSubprocess();
|
||||||
|
|
||||||
$this->assertEquals('Done', $out);
|
$this->assertEquals('Done', $out);
|
||||||
|
|
||||||
|
// Exceptions
|
||||||
|
|
||||||
|
$chain = new ErrorControlChainTest_Chain();
|
||||||
|
|
||||||
|
list($out, $code) = $chain
|
||||||
|
->then(function(){
|
||||||
|
throw new Exception("bob");
|
||||||
|
})
|
||||||
|
->thenIfErrored(function(){
|
||||||
|
echo "Done";
|
||||||
|
})
|
||||||
|
->executeInSubprocess();
|
||||||
|
|
||||||
|
$this->assertEquals('Done', $out);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testExceptionSuppression() {
|
function testExceptionSuppression() {
|
||||||
|
Loading…
Reference in New Issue
Block a user