1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 11:30:55 +01:00

Improve XHPAST handling of syntax errors

Summary: Currently, a bunch of developers are using #xhpast for writing custom linter rules. As such, we end up with a fair few `XHPASTSyntaxErrorException` in our PHP error logs. I think that throwing an exception is not quite correct in this case because it is somewhat expected that invalid PHP may be entered. Instead, catch the exception and show the user a helpful message.

Test Plan: This doesn't quite work yet... the stream and tree views render as blank but the exceptions still propogate to the error logs. Mostly, I'm not sure how the exception should be rendered for display.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D14028
This commit is contained in:
Joshua Spence 2015-11-08 21:54:47 +11:00 committed by Joshua Spence
parent c3ecea9788
commit a2f909f0bd
9 changed files with 54 additions and 34 deletions

View file

@ -0,0 +1,5 @@
ALTER TABLE {$NAMESPACE}_xhpastview.xhpastview_parsetree
ADD returnCode INT NOT NULL AFTER input;
ALTER TABLE {$NAMESPACE}_xhpastview.xhpastview_parsetree
ADD stderr longtext NOT NULL AFTER stdout;

View file

@ -3,7 +3,6 @@
abstract class PhabricatorXHPASTViewController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('XHPASTView');

View file

@ -14,7 +14,7 @@ final class PhabricatorXHPASTViewFrameController
phutil_tag(
'iframe',
array(
'src' => '/xhpast/frameset/'.$id.'/',
'src' => "/xhpast/frameset/{$id}/",
'frameborder' => '0',
'style' => 'width: 100%; height: 800px;',
'',

View file

@ -10,17 +10,15 @@ final class PhabricatorXHPASTViewFramesetController
public function handleRequest(AphrontRequest $request) {
$id = $request->getURIData('id');
$response = new AphrontWebpageResponse();
$response->setFrameable(true);
$response->setContent(phutil_tag(
'frameset',
array('cols' => '33%, 34%, 33%'),
array(
phutil_tag('frame', array('src' => "/xhpast/input/{$id}/")),
phutil_tag('frame', array('src' => "/xhpast/tree/{$id}/")),
phutil_tag('frame', array('src' => "/xhpast/stream/{$id}/")),
)));
return $response;
return id(new AphrontWebpageResponse())
->setFrameable(true)
->setContent(phutil_tag(
'frameset',
array('cols' => '33%, 34%, 33%'),
array(
phutil_tag('frame', array('src' => "/xhpast/input/{$id}/")),
phutil_tag('frame', array('src' => "/xhpast/tree/{$id}/")),
phutil_tag('frame', array('src' => "/xhpast/stream/{$id}/")),
)));
}
}

View file

@ -14,6 +14,7 @@ abstract class PhabricatorXHPASTViewPanelController
$this->id = $data['id'];
$this->storageTree = id(new PhabricatorXHPASTViewParseTree())
->load($this->id);
if (!$this->storageTree) {
throw new Exception(pht('No such AST!'));
}
@ -65,10 +66,9 @@ li span {
'</html>',
$content);
$response = new AphrontWebpageResponse();
$response->setFrameable(true);
$response->setContent($content);
return $response;
return id(new AphrontWebpageResponse())
->setFrameable(true)
->setContent($content);
}
}

View file

@ -13,17 +13,21 @@ final class PhabricatorXHPASTViewRunController
$resolved = $future->resolve();
// This is just to let it throw exceptions if stuff is broken.
$parse_tree = XHPASTTree::newFromDataAndResolvedExecFuture(
$source,
$resolved);
try {
XHPASTTree::newFromDataAndResolvedExecFuture($source, $resolved);
} catch (XHPASTSyntaxErrorException $ex) {
// This is possibly expected.
}
list($err, $stdout, $stderr) = $resolved;
$storage_tree = new PhabricatorXHPASTViewParseTree();
$storage_tree->setInput($source);
$storage_tree->setStdout($stdout);
$storage_tree->setAuthorPHID($viewer->getPHID());
$storage_tree->save();
$storage_tree = id(new PhabricatorXHPASTViewParseTree())
->setInput($source)
->setReturnCode($err)
->setStdout($stdout)
->setStderr($stderr)
->setAuthorPHID($viewer->getPHID())
->save();
return id(new AphrontRedirectResponse())
->setURI('/xhpast/view/'.$storage_tree->getID().'/');

View file

@ -6,11 +6,17 @@ final class PhabricatorXHPASTViewStreamController
public function handleRequest(AphrontRequest $request) {
$storage = $this->getStorageTree();
$input = $storage->getInput();
$err = $storage->getReturnCode();
$stdout = $storage->getStdout();
$stderr = $storage->getStderr();
$tree = XHPASTTree::newFromDataAndResolvedExecFuture(
$input,
array(0, $stdout, ''));
try {
$tree = XHPASTTree::newFromDataAndResolvedExecFuture(
$input,
array($err, $stdout, $stderr));
} catch (XHPASTSyntaxErrorException $ex) {
return $this->buildXHPASTViewPanelResponse($ex->getMessage());
}
$tokens = array();
foreach ($tree->getRawTokenStream() as $id => $token) {

View file

@ -10,18 +10,23 @@ final class PhabricatorXHPASTViewTreeController
public function handleRequest(AphrontRequest $request) {
$storage = $this->getStorageTree();
$input = $storage->getInput();
$err = $storage->getReturnCode();
$stdout = $storage->getStdout();
$stderr = $storage->getStderr();
$tree = XHPASTTree::newFromDataAndResolvedExecFuture(
$input,
array(0, $stdout, ''));
try {
$tree = XHPASTTree::newFromDataAndResolvedExecFuture(
$input,
array($err, $stdout, $stderr));
} catch (XHPASTSyntaxErrorException $ex) {
return $this->buildXHPASTViewPanelResponse($ex->getMessage());
}
$tree = phutil_tag('ul', array(), $this->buildTree($tree->getRootNode()));
return $this->buildXHPASTViewPanelResponse($tree);
}
protected function buildTree($root) {
try {
$name = $root->getTypeName();
$title = $root->getDescription();

View file

@ -3,16 +3,19 @@
final class PhabricatorXHPASTViewParseTree extends PhabricatorXHPASTViewDAO {
protected $authorPHID;
protected $input;
protected $returnCode;
protected $stdout;
protected $stderr;
protected function getConfiguration() {
return array(
self::CONFIG_COLUMN_SCHEMA => array(
'authorPHID' => 'phid?',
'input' => 'text',
'returnCode' => 'sint32',
'stdout' => 'text',
'stderr' => 'text',
),
) + parent::getConfiguration();
}