Skip to content

Commit

Permalink
Error recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt committed Jun 11, 2015
1 parent 7318106 commit 9aca313
Show file tree
Hide file tree
Showing 11 changed files with 679 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/Recovery/Code/Excerpt.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/**
* @package Outpost
* @author Pixo <[email protected]>
* @copyright 2015, Pixo
* @license http://opensource.org/licenses/NCSA NCSA
*/

namespace Outpost\Recovery\Code;

class Excerpt {

protected $file;
protected $line;
protected $radius;

public function __construct($file, $line, $radius = 5) {
$this->file = $file;
$this->line = $line;
$this->radius = $radius;
}

public function __toString() {
$firstLine = $this->line - $this->radius;
$lastLine = $this->line + $this->radius;
if ($firstLine < 1) {
$lastLine += -$firstLine;
$firstLine = 1;
}
$fp = fopen($this->file, 'r');
$lineNumber = 0;
$excerpt = array();
while ($line = fgets($fp, 1024)) {
$lineNumber++;
if ($lineNumber >= $firstLine) {
$excerpt[$lineNumber] = new Line($line, $lineNumber, $lineNumber == $this->line);
}
if ($lineNumber >= $lastLine) {
break;
}
}
if (!empty($excerpt)) {
$str = '<p>' . $this->file . ', line ' . $this->line . '</p>';
$str .= '<div class="code">' . implode('', $excerpt) . '</div>';
return $str;
}
return '';
}

}
38 changes: 38 additions & 0 deletions src/Recovery/Code/Line.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/**
* @package Outpost
* @author Pixo <[email protected]>
* @copyright 2015, Pixo
* @license http://opensource.org/licenses/NCSA NCSA
*/

namespace Outpost\Recovery\Code;

class Line {

protected $code;
protected $highlighted;
protected $number;

public function __construct($code, $number, $highlighted = false) {
$this->code = $code;
$this->number = $number;
$this->highlighted = $highlighted;
}

public function __toString() {
$html = '<span class="number">' . $this->number . '</span> ';
$html .= '<code>' . htmlentities($this->code) . '</code>';
$lineClass = $this->highlighted ? 'highlighted line' : 'line';
return "<div class=\"{$lineClass}\">$html</div>";
}

public function getCode() {
return $this->code;
}

public function getNumber() {
return $this->number;
}
}
14 changes: 14 additions & 0 deletions src/Recovery/HasDescriptionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* @package Outpost
* @author Pixo <[email protected]>
* @copyright 2015, Pixo
* @license http://opensource.org/licenses/NCSA NCSA
*/

namespace Outpost\Recovery;

interface HasDescriptionInterface {
public function getDescription();
}
14 changes: 14 additions & 0 deletions src/Recovery/HasRepairInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* @package Outpost
* @author Pixo <[email protected]>
* @copyright 2015, Pixo
* @license http://opensource.org/licenses/NCSA NCSA
*/

namespace Outpost\Recovery;

interface HasRepairInterface {
public function getRepair();
}
102 changes: 102 additions & 0 deletions src/Recovery/HelpPage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

/**
* @package Outpost
* @author Pixo <[email protected]>
* @copyright 2015, Pixo
* @license http://opensource.org/licenses/NCSA NCSA
*/

namespace Outpost\Recovery;

use Outpost\Html\Document;
use Outpost\Recovery\Code\Excerpt;
use Outpost\Recovery\Trace\Stack;
use Outpost\SiteInterface;

class HelpPage {

protected $exception;

public static function getOutpostPath() {
return realpath(__DIR__ . '/..');
}

public static function isOutpostPath($path) {
$prefix = self::getOutpostPath() . '/';
return substr(realpath($path), 0, strlen($prefix)) == $prefix;
}

public static function makeExceptionString(\Exception $e) {
return sprintf("%s (%s, line %d)", $e->getMessage(), $e->getFile(), $e->getLine());
}

public function __construct(\Exception $exception, SiteInterface $site = null) {
$this->exception = $exception;
if (isset($site)) $this->site = $site;
}

public function __toString() {
try {
return (string)$this->makePage();
}
catch (\Exception $e) {
return self::makeExceptionString($e);
}
}

protected function makePage() {
if ($previous = $this->exception->getPrevious()) {
$page = new HelpPage($previous);
return $page->makePage();
}
$vars = [
'title'=> $this->makeTitle(),
# 'excerpt' => $this->makeCodeExcerpt(),
'trace' => @\Kint::trace($this->exception->getTrace()),
];
if ($this->exception instanceof HasDescriptionInterface) {
$vars['description'] = $this->exception->getDescription();
}
else {
$vars['description'] = '<h1>' . $this->exception->getMessage() . '</h1>';
}
if ($this->exception instanceof HasRepairInterface) {
$vars['repairInstructions'] = $this->exception->getRepair();
}
$document = new Document($this->render("page.php", $vars), 'ATTENTION');
$document->addStyles(file_get_contents(__DIR__ . '/templates/help.css'));
return $document;
}

protected function makeCodeExcerpt() {
return new Excerpt($this->exception->getFile(), $this->exception->getLine());
}

protected function makeTitle() {
if ($message = $this->exception->getMessage()) return $message;
$exceptionClass = new \ReflectionClass($this->exception);
return $exceptionClass->getShortName();
}

protected function makeTrace() {
return new Stack($this->exception);
}

protected function isOutpostException() {
return self::isOutpostPath($this->exception->getFile());
}

protected function render($template, array $variables = []) {
extract($variables);
ob_start();
include __DIR__ . "/templates/$template";
$content = ob_get_contents();
ob_end_clean();
return $content;
}

protected function debug($var) {
return @\Kint::dump($var);
}
}
20 changes: 20 additions & 0 deletions src/Recovery/HelpResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* @package Outpost
* @author Pixo <[email protected]>
* @copyright 2015, Pixo
* @license http://opensource.org/licenses/NCSA NCSA
*/

namespace Outpost\Recovery;

use Symfony\Component\HttpFoundation\Response;

class HelpResponse extends Response {

public function __construct(\Exception $e, $status = 500, $headers = array()) {
$page = new HelpPage($e);
parent::__construct((string)$page, $status, $headers);
}
}
Loading

0 comments on commit 9aca313

Please sign in to comment.