Skip to content

Commit

Permalink
Merge branch 'fix-stack-queue'
Browse files Browse the repository at this point in the history
  • Loading branch information
denis-sokolov committed Dec 25, 2019
2 parents 5830721 + fca08ca commit ecbc8f3
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 96 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,7 @@
# 2.6.0

* Fix 2.4.0 pushHandler changing the order of handlers.

# 2.5.1

* Fix error messaging in a rare case.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -62,7 +62,7 @@ If you are not using any of these frameworks, here's a very simple way to instal

```php
$whoops = new \Whoops\Run;
$whoops->prependHandler(new \Whoops\Handler\PrettyPageHandler);
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
$whoops->register();
```

Expand Down
6 changes: 3 additions & 3 deletions examples/example-ajax-only.php
Expand Up @@ -26,7 +26,7 @@

// We want the error page to be shown by default, if this is a
// regular request, so that's the first thing to go into the stack:
$run->prependHandler(new PrettyPageHandler());
$run->pushHandler(new PrettyPageHandler());

// Now, we want a second handler that will run before the error page,
// and immediately return an error message in JSON format, if something
Expand All @@ -42,8 +42,8 @@
// tl;dr: error[] becomes errors[[]]
$jsonHandler->setJsonApi(true);

// And prepend it into the stack:
$run->prependHandler($jsonHandler);
// And push it into the stack:
$run->pushHandler($jsonHandler);
}

// That's it! Register Whoops and throw a dummy exception:
Expand Down
4 changes: 2 additions & 2 deletions examples/example.php
Expand Up @@ -50,10 +50,10 @@ class Exception extends BaseException
return $data;
});

$run->prependHandler($handler);
$run->pushHandler($handler);

// Example: tag all frames inside a function with their function name
$run->prependHandler(function ($exception, $inspector, $run) {
$run->pushHandler(function ($exception, $inspector, $run) {

$inspector->getFrames()->map(function ($frame) {

Expand Down
97 changes: 36 additions & 61 deletions src/Whoops/Run.php
Expand Up @@ -29,7 +29,7 @@ final class Run implements RunInterface
/**
* @var HandlerInterface[]
*/
private $handlerQueue = [];
private $handlerStack = [];

private $silencedPatterns = [];

Expand All @@ -41,105 +41,64 @@ public function __construct(SystemFacade $system = null)
}

/**
* Prepends a handler to the start of the queue
*
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
* @param Callable|HandlerInterface $handler
* @return Run
* @deprecated use appendHandler and prependHandler instead
*/
public function pushHandler($handler)
{
return $this->prependHandler($handler);
}

/**
* Appends a handler to the end of the queue
*
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
* @param Callable|HandlerInterface $handler
* @return Run
* Explicitly request your handler runs as the last of all currently registered handlers
*/
public function appendHandler($handler)
{
array_push($this->handlerQueue, $this->resolveHandler($handler));
array_unshift($this->handlerStack, $this->resolveHandler($handler));
return $this;
}

/**
* Prepends a handler to the start of the queue
*
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
* @param Callable|HandlerInterface $handler
* @return Run
* Explicitly request your handler runs as the first of all currently registered handlers
*/
public function prependHandler($handler)
{
array_unshift($this->handlerQueue, $this->resolveHandler($handler));
return $this;
return $this->pushHandler($handler);
}

/**
* Create a CallbackHandler from callable and throw if handler is invalid
* Register your handler as the last of all currently registered handlers.
* Prefer using appendHandler and prependHandler for clarity.
*
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
* @param Callable|HandlerInterface $handler
* @return HandlerInterface
* @param Callable|HandlerInterface $handler
* @return Run
*/
private function resolveHandler($handler)
public function pushHandler($handler)
{
if (is_callable($handler)) {
$handler = new CallbackHandler($handler);
}

if (!$handler instanceof HandlerInterface) {
throw new InvalidArgumentException(
"Argument to " . __METHOD__ . " must be a callable, or instance of "
. "Whoops\\Handler\\HandlerInterface"
);
}

return $handler;
$this->handlerStack[] = $this->resolveHandler($handler);
return $this;
}

/**
* Removes the last handler in the queue and returns it.
* Removes the last handler in the stack and returns it.
* Returns null if there"s nothing else to pop.
* @return null|HandlerInterface
*/
public function popHandler()
{
return array_pop($this->handlerQueue);
}

/**
* Removes the first handler in the queue and returns it.
* Returns null if there"s nothing else to shift.
* @return null|HandlerInterface
*/
public function shiftHandler()
{
return array_shift($this->handlerQueue);
return array_pop($this->handlerStack);
}

/**
* Returns an array with all handlers, in the
* order they were added to the queue.
* order they were added to the stack.
* @return array
*/
public function getHandlers()
{
return $this->handlerQueue;
return $this->handlerStack;
}

/**
* Clears all handlers in the handlerQueue, including
* Clears all handlers in the handlerStack, including
* the default PrettyPage handler.
* @return Run
*/
public function clearHandlers()
{
$this->handlerQueue = [];
$this->handlerStack = [];
return $this;
}

Expand Down Expand Up @@ -303,13 +262,13 @@ public function handleException($exception)
// we might want to send it straight away to the client,
// or return it silently.
$this->system->startOutputBuffering();

// Just in case there are no handlers:
$handlerResponse = null;
$handlerContentType = null;

try {
foreach ($this->handlerQueue as $handler) {
foreach (array_reverse($this->handlerStack) as $handler) {
$handler->setRun($this);
$handler->setInspector($inspector);
$handler->setException($exception);
Expand Down Expand Up @@ -441,6 +400,22 @@ public function handleShutdown()
*/
private $canThrowExceptions = true;

private function resolveHandler($handler)
{
if (is_callable($handler)) {
$handler = new CallbackHandler($handler);
}

if (!$handler instanceof HandlerInterface) {
throw new InvalidArgumentException(
"Handler must be a callable, or instance of "
. "Whoops\\Handler\\HandlerInterface"
);
}

return $handler;
}

/**
* Echo something to the browser
* @param string $output
Expand Down

2 comments on commit ecbc8f3

@gnumoksha
Copy link

@gnumoksha gnumoksha commented on ecbc8f3 Dec 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change it?
What about #635 ?

@denis-sokolov
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #639 (comment) for further details.

Please sign in to comment.