Skip to content

Instantly share code, notes, and snippets.

@jul
Last active October 26, 2016 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jul/406da833d99e545085dac2f368a3b850 to your computer and use it in GitHub Desktop.
Save jul/406da833d99e545085dac2f368a3b850 to your computer and use it in GitHub Desktop.
JSON error higlighter
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""SYNOPSIS
=======
Validate a JSON given as an argument or in stdin.
If the result is correct return it indented
If an error is detected print the result on stdout (and try to place ',' if possible)
with the error highlighted according to the indication of json.loads error message
and print the error message on stdout.
OPTION
======
-h display this help
ERROR
=====
returns 1 on failure, 2 on help
"""
from __future__ import print_function
import sys
from json import loads, dumps
import re
from sys import argv
to_valid = None
if len(sys.argv) >= 2:
if sys.argv[1] != '-h' and len(sys.argv) == 2:
to_valid = sys.argv[1]
else:
print(__doc__)
sys.exit(2)
else:
to_valid = "".join(sys.stdin)
if to_valid is not None:
output = ""
try:
res = loads(to_valid)
output = dumps(res, indent=4)
sys.stdout.write("%s\n" % output)
except ValueError as e:
# py2/3 gory way, mouhahahaha
if hasattr(e, "message"):
e = e.message
char_bef = 0
char_aft = -1
to_valid+=" \n"
mark = re.search(r'line \d+ column \d+ \(char (?P<before>\d+)( \- (?P<after>\d+))?\)', str(e))
if mark:
mark = mark.groupdict()
else:
to_valid+="\n"
mark = dict(before = 0, after=-1)
char_bef = int(mark["before"])
char_aft = int(mark["after"] or (char_bef))
output = to_valid[:char_bef]
FAIL = '\033[36;45;1m'
ENDC = '\033[0m'
output += FAIL
delim = re.search("Expecting (.) ", str(e))
if delim:
output += delim.group(1)
else:
char_aft += 1
output += to_valid[char_bef:char_aft]
output += ENDC
output += to_valid[char_aft:]
print(output)
sys.stderr.write("*" * 80 + "\n" + "ERROR DETECTED :\n" + FAIL + str(e)+ ENDC + "\n")
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment