Page MenuHomePhabricator

D9624.id23116.diff
No OneTemporary

D9624.id23116.diff

diff --git a/src/parser/PhutilJSONParser.php b/src/parser/PhutilJSONParser.php
--- a/src/parser/PhutilJSONParser.php
+++ b/src/parser/PhutilJSONParser.php
@@ -19,7 +19,15 @@
try {
$output = $parser->parse($json);
} catch (JsonLintParsingException $ex) {
- throw new PhutilJSONParserException($ex->getMessage());
+ $details = $ex->getDetails();
+ $message = preg_replace("/^Parse error .*\\^\n/s", '', $ex->getMessage());
+
+ throw new PhutilJSONParserException(
+ $message,
+ $details['loc']['last_line'],
+ $details['loc']['last_column'],
+ $details['token'],
+ $details['expected']);
}
if (!is_array($output)) {
diff --git a/src/parser/__tests__/PhutilJSONParserTestCase.php b/src/parser/__tests__/PhutilJSONParserTestCase.php
--- a/src/parser/__tests__/PhutilJSONParserTestCase.php
+++ b/src/parser/__tests__/PhutilJSONParserTestCase.php
@@ -30,19 +30,49 @@
$parser = new PhutilJSONParser();
$tests = array(
- '',
- 'null',
- 'false',
- 'true',
- '"quack quack I am a duck lol"',
- '{',
- '[',
- '{"foo":',
- '{"foo":"bar",}',
- '{{}',
+ '{' => array(
+ 'line' => 1,
+ 'char' => 1,
+ 'token' => 'EOF',
+ ),
+ '[' => array(
+ 'line' => 1,
+ 'char' => 1,
+ 'token' => 'EOF',
+ ),
+ '{"foo":' => array(
+ 'line' => 1,
+ 'char' => 7,
+ 'token' => 'EOF',
+ ),
+ '{"foo":"bar",}' => array(
+ 'line' => 1,
+ 'char' => 13,
+ 'token' => '}',
+ ),
+ '{{}' => array(
+ 'line' => 1,
+ 'char' => 1,
+ 'token' => '{',
+ ),
+ '{}}' => array(
+ 'line' => 1,
+ 'char' => 2,
+ 'token' => '}',
+ ),
+ "{\"foo\":\"bar\",\n\"bar\":\"baz\",}" => array(
+ 'line' => 2,
+ 'char' => 12,
+ 'token' => '}',
+ ),
+ "{'foo': 'bar'}" => array(
+ 'line' => 1,
+ 'char' => 1,
+ 'token' => 'INVALID',
+ ),
);
- foreach ($tests as $input) {
+ foreach ($tests as $input => $expected) {
$caught = null;
try {
$parser->parse($input);
@@ -50,6 +80,9 @@
$caught = $ex;
}
$this->assertTrue($caught instanceof PhutilJSONParserException);
+ $this->assertEqual($expected['line'], $caught->getSourceLine());
+ $this->assertEqual($expected['char'], $caught->getSourceChar());
+ $this->assertEqual($expected['token'], $caught->getSourceToken());
}
}
diff --git a/src/parser/exception/PhutilJSONParserException.php b/src/parser/exception/PhutilJSONParserException.php
--- a/src/parser/exception/PhutilJSONParserException.php
+++ b/src/parser/exception/PhutilJSONParserException.php
@@ -1,3 +1,41 @@
<?php
-final class PhutilJSONParserException extends Exception {}
+final class PhutilJSONParserException extends Exception {
+
+ private $sourceLine;
+ private $sourceChar;
+ private $sourceToken;
+ private $expected;
+
+ public function __construct(
+ $message,
+ $line = null,
+ $char = null,
+ $token = null,
+ $expected = null) {
+
+ $this->sourceLine = $line;
+ $this->sourceChar = $char;
+ $this->sourceToken = $token;
+ $this->expected = $expected;
+
+ parent::__construct($message);
+ }
+
+ public function getSourceLine() {
+ return $this->sourceLine;
+ }
+
+ public function getSourceChar() {
+ return $this->sourceChar;
+ }
+
+ public function getSourceToken() {
+ return $this->sourceToken;
+ }
+
+ public function getExpectedTokens() {
+ return $this->expected;
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 21, 5:02 PM (3 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6714939
Default Alt Text
D9624.id23116.diff (3 KB)

Event Timeline