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:
parent
c3ecea9788
commit
a2f909f0bd
9 changed files with 54 additions and 34 deletions
5
resources/sql/autopatches/20151108.xhpast.stderr.sql
Normal file
5
resources/sql/autopatches/20151108.xhpast.stderr.sql
Normal 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;
|
|
@ -3,7 +3,6 @@
|
|||
abstract class PhabricatorXHPASTViewController extends PhabricatorController {
|
||||
|
||||
public function buildStandardPageResponse($view, array $data) {
|
||||
|
||||
$page = $this->buildStandardPageView();
|
||||
|
||||
$page->setApplicationName('XHPASTView');
|
||||
|
|
|
@ -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;',
|
||||
'',
|
||||
|
|
|
@ -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}/")),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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().'/');
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue