Skip to content

Commit 89f7b2a

Browse files
committed
Web Inspector: improve error message when code generator is unable to parse JSON
https://bugs.webkit.org/show_bug.cgi?id=289613 Reviewed by Devin Rousso. Having the error context readily available makes it much easier to edit protocol JSON files. * Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py: (generate_from_specification.load_specification): Save the filename so it can be used later in the topmost exception handler to create a nice error message. Print the error message to stderr so that failure results can be correctly interpreted by `run-inspector-generator-tests --reset-results`. * Source/JavaScriptCore/inspector/scripts/tests/expected/fail-on-invalid-json-with-context.json-error: Added. * Source/JavaScriptCore/inspector/scripts/tests/fail-on-invalid-json-with-context.json: Added. * Tools/Scripts/webkitpy/style/checker.py: Skip checking of JSON syntax in the Inspector code generator tests directory. We intentionally use some invalid JSON inputs starting with this change. Canonical link: https://commits.webkit.org/292123@main
1 parent 8e00808 commit 89f7b2a

4 files changed

Lines changed: 44 additions & 2 deletions

File tree

‎Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
except ImportError:
4242
import simplejson as json
4343

44+
from json import JSONDecodeError
45+
4446
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR)
4547
log = logging.getLogger('global')
4648

@@ -127,8 +129,10 @@ def load_specification(protocol, filepath, isSupplemental=False):
127129
regex = re.compile(r"\/\*.*?\*\/", re.DOTALL)
128130
parsed_json = json.loads(re.sub(regex, "", input_file.read()))
129131
protocol.parse_specification(parsed_json, isSupplemental)
130-
except ValueError as e:
131-
raise Exception("Error parsing valid JSON in file: " + filepath + "\nParse error: " + str(e))
132+
except JSONDecodeError as e:
133+
# There's no way to get the filename from the outer exception handler, so insert it here.
134+
setattr(e, 'input_filename', input_file.name)
135+
raise
132136

133137
protocol = models.Protocol(framework_name)
134138
for specification in supplemental_specification_filepaths:
@@ -304,6 +308,17 @@ def load_specification(protocol, filepath, isSupplemental=False):
304308

305309
try:
306310
generate_from_specification(**options)
311+
except JSONDecodeError as e:
312+
message_lines = [
313+
"Parse error trying to decode JSON!\n",
314+
"error: {} at {}:{}:{}\n".format(e.msg, getattr(e, 'input_filename', '<unkwown>'), e.lineno, e.colno),
315+
e.doc[:e.pos],
316+
'~' * (e.colno - 1) + "^ // line {}, col {}: {}".format(e.lineno, e.colno, e.msg),
317+
]
318+
log.error("\n".join(message_lines))
319+
if not arg_options.test:
320+
raise # Force the build to fail after printing full message.
321+
307322
except (ParseException, TypecheckException) as e:
308323
if arg_options.test:
309324
log.error(str(e))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
ERROR: Parse error trying to decode JSON!
2+
3+
error: Expecting value at JavaScriptCore/inspector/scripts/tests/fail-on-invalid-json-with-context.json:9:1
4+
5+
{
6+
"domain": "Database",
7+
"types": [
8+
{
9+
"id": "DatabaseId",
10+
"type": "integer",
11+
"description": "Unique identifier of Database object."
12+
},
13+
14+
^ // line 9, col 1: Expecting value
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"domain": "Database",
3+
"types": [
4+
{
5+
"id": "DatabaseId",
6+
"type": "integer",
7+
"description": "Unique identifier of Database object."
8+
},
9+
}

‎Tools/Scripts/webkitpy/style/checker.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@
354354
os.path.join('Source', 'JavaScriptCore', 'jit', 'GDBInterface.cpp')],
355355
["-readability/naming"]),
356356

357+
([ # Some test cases intentionally use invalid JSON input files.
358+
os.path.join('Source', 'JavaScriptCore', 'inspector', 'scripts', 'tests')],
359+
["-json/syntax"]),
360+
357361
([ # On some systems the trailing CR is causing parser failure.
358362
os.path.join('Source', 'JavaScriptCore', 'parser', 'Keywords.table')],
359363
["+whitespace/carriage_return"]),

0 commit comments

Comments
 (0)