There is a rule in Python programming called "it is Easier to Ask for Forgiveness than for Permission" (in short: EAFP). It means that you should catch exceptions instead of checking values for validity.
Thus, try the following:
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except ValueError: # includes simplejson.decoder.JSONDecodeError
print('Decoding JSON has failed')
EDIT: Since simplejson.decoder.JSONDecodeError actually inherits from ValueError (proof here), I simplified the catch statement by just using ValueError.
python - Handle JSON Decode Error when nothing returned - Stack Overflow
Python json.loads() returns JSONDecodeError - Stack Overflow
How to get error location from json.loads in Python - Stack Overflow
Python json.loads doesn't work - Stack Overflow
JSON doc:
{
"Data" : [
"input1",
"input2",
"input3",
"input4"
]
}Python code:
import json
with open("data.json", 'r') as f:
json_data = json.load(f)
print(json_data)Error message:
sh-5.1$ /bin/python /home/USER/Documents/Python/learning
Traceback (most recent call last):
File "/home/USER/Documents/Python/learning", line 27, in <module>
json_data = json.load(f)
File "/usr/lib/python3.9/json/__init__.py", line 293, in load
return loads(fp.read(),
File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)Disproved theories: Improper syntax (python), document not located, bad formatting (json), accidental empty space in json.
I get this error each time I try to use "json.load" so long as it has a valid parameter input. Whether read or write; error. I'm using Visual Studio Code on Linux Mint in case that matters.
Thanks for your time! I'll be happy to answer questions in the morning when I wake up.
EDIT: Clarity, and reddit dislikes my use of backticks. Manually tabbed code.
EDIT: This code SHOULD work. It does on other computers. But it doesn't on mine, and I don't know why nor how to fix it.
There is a rule in Python programming called "it is Easier to Ask for Forgiveness than for Permission" (in short: EAFP). It means that you should catch exceptions instead of checking values for validity.
Thus, try the following:
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except ValueError: # includes simplejson.decoder.JSONDecodeError
print('Decoding JSON has failed')
EDIT: Since simplejson.decoder.JSONDecodeError actually inherits from ValueError (proof here), I simplified the catch statement by just using ValueError.
If you don't mind importing the json module, then the best way to handle it is through json.JSONDecodeError (or json.decoder.JSONDecodeError as they are the same) as using default errors like ValueError could catch also other exceptions not necessarily connected to the json decode one.
from json.decoder import JSONDecodeError
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
# do whatever you want
//EDIT (Oct 2020):
As @Jacob Lee noted in the comment, there could be the basic common TypeError raised when the JSON object is not a str, bytes, or bytearray. Your question is about JSONDecodeError, but still it is worth mentioning here as a note; to handle also this situation, but differentiate between different issues, the following could be used:
from json.decoder import JSONDecodeError
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
# do whatever you want
except TypeError as e:
# do whatever you want in this case
[This answer is outdated. See other answers for modern python versions]
Scanning the json/decoder.py source code, we can see that the decoder's error messages are constructed using the errmsg function:
Copydef errmsg(msg, doc, pos, end=None):
# Note that this function is called from _json
lineno, colno = linecol(doc, pos)
if end is None:
fmt = '{0}: line {1} column {2} (char {3})'
return fmt.format(msg, lineno, colno, pos)
#fmt = '%s: line %d column %d (char %d)'
#return fmt % (msg, lineno, colno, pos)
endlineno, endcolno = linecol(doc, end)
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
#fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'
#return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)
Since this is a pure-python module, it's easy to wrap this function with a custom one. This process is known as monkey patching:
Copyimport json
original_errmsg= json.decoder.errmsg
def our_errmsg(msg, doc, pos, end=None):
json.last_error_position= json.decoder.linecol(doc, pos)
return original_errmsg(msg, doc, pos, end)
json.decoder.errmsg= our_errmsg
try:
data = json.loads('{1:}')
except ValueError as e:
print("error at", json.last_error_position)
Obviously, this solution is not ideal, since the implementation may change at any time, although it's still better than relying on the message. You should check if errmsg exists before patching (and possibly if there's no other arguments, or use varargs).
If you use simplejson library, you get a well qualified JSONDecodeError:
Copyclass JSONDecodeError(ValueError):
"""Subclass of ValueError with the following additional properties:
msg: The unformatted error message
doc: The JSON document being parsed
pos: The start index of doc where parsing failed
end: The end index of doc where parsing failed (may be None)
lineno: The line corresponding to pos
colno: The column corresponding to pos
endlineno: The line corresponding to end (may be None)
endcolno: The column corresponding to end (may be None)
"""
Hopefully, this will be merged into stdlib soon.
Your JSON data is enclosed in extra quotes making it a JSON string, and the data contained within that string is not JSON.
Print repr(decData) instead, you'll get:
'"{\'name\' : \'journal2\'}"'
and the JSON library is correctly interpreting that as one string with the literal contents {'name' : 'journal2'}. If you stripped the outer quotes, the contained characters are not valid JSON, because JSON strings must always be enclosed in double quotes.
For all the json module is concerned, decData could just as well have contained "This is not JSON" and postData would have been set to u'This is not JSON'.
>>> import json
>>> decData = '''"{'name' : 'journal2'}"'''
>>> json.loads(decData)
u"{'name' : 'journal2'}"
>>> json.loads(json.loads(decData))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 326, in loads
return _default_decoder.decode(s)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 1 (char 1)
Fix whatever is producing this string, your view is fine, it's the input that is broken.
To workaround the error 'Expecting property name enclosed in double quotes' you can do:
import json
data = "{'name' : 'journal2'}"
json.loads(json.dumps(data))
I'm completely new to using the python json library, and I'm not sure how to interpret an error message. In my code, I'm calling json.loads() on a (albeit awfully complex) string, and it doesn't seem to like my input. Here's the string it's called on:
[[{"@context":"http://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://people.com/","name":"Home","image":None}},{"@type":"ListItem","position":2,"item":{"@id":"https://people.com/celebrity/","name":"Celebrity","image":None}},{"@type":"ListItem","position":3,"item":{"@id":"https://people.com/parents/","name":"Parents","image":None}}]},{"@context":"http://schema.org","@type":"NewsArticle","headline":"Meet+the+Man+Behind+Daddy+Pig:+Richard+Ridings+on+'Keeping+the+Magic+Alive'+for+18+Years","image":[{"@type":"ImageObject","url":"https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F20%2F2022%2F07%2F28%2Fdaddy-pig-richard-ridings-072822.jpg","width":1500,"height":1000},{"@type":"ImageObject","url":"https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F20%2F2022%2F07%2F28%2Fpeppa-pig-daddy-pig-072822.jpg"}],"author":[{"@type":"Person","name":"Georgia+Slater","url":"https://people.com/author/georgia-slater/","sameAs":["https://twitter.com/georgiahslater"]}],"publisher":{"@type":"Organization","name":"PEOPLE.com","url":"https://people.com","logo":{"@type":"ImageObject","url":"https://people.com/img/logo.png","width":120,"height":60},"sameAs":["https://www.facebook.com/peoplemag","https://twitter.com/people","https://www.pinterest.com/people/","https://www.instagram.com/people/","https://www.youtube.com/user/people","https://www.snapchat.com/discover/People-Magazine/0407249978"]},"datePublished":"2022-07-29T18:50:22-05:00","dateModified":"2022-07-29T18:50:22-05:00","description":"Richard+Ridings+has+been+voicing+the+beloved+character+Daddy+Pig+on+the+popular+children's+show+<em>Peppa+Pig</em>+for+nearly+two+decades+—+and+he's+not+stopping+anytime+soon","mainEntityOfPage":"https://people.com/parents/daddy-pig-richard-ridings-on-keeping-the-magic-alive-for-18-years-exclusive/"}]]and here's the error I get:
Traceback (most recent call last):
File "/Users/achatterjee/Documents/MITM Analysis/test_flatten.py", line 3, in <module>
print(json.loads(string1))
File "/Users/achatterjee/opt/anaconda3/lib/python3.9/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/Users/achatterjee/opt/anaconda3/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Users/achatterjee/opt/anaconda3/lib/python3.9/json/decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 4 (char 3)I'm not entirely sure how to interpret this error, as I'm new to using the json library. Any and all help is very much appreciated, thank you.
Another option, perhaps, is to use the strict=False argument
According to http://docs.python.org/2/library/json.html
"If strict is False (True is the default), then control characters will be allowed inside strings. Control characters in this context are those with character codes in the 0-31 range, including '\t' (tab), '\n', '\r' and '\0'."
For example:
json.loads(json_str, strict=False)
The problem is your unicode string contains carriage returns (\r) and newlines (\n) within a string literal in the JSON data. If they were meant to be part of the string itself, they should be escaped appropriately. If they weren't meant to be part of the string, they shouldn't be in your JSON either.
If you can't fix where you got this JSON string to produce valid JSON, you could either remove the offending characters:
>>> json.loads(s.replace('\r\n', ''))
or escape them manually:
>>> json.loads(s.replace('\r\n', '\\r\\n'))
JSON is a subset of JavaScript. This means things that are valid JavaScript are not necessarily valid JSON.
{"A":2,}is valid JS (except in old IE versions), but not valid JSON['A':2}is not even valid JS since the braces do not match. If they matched, it would still be invalid JSON as JSON always uses"and never'to quote strings.
See http://json.org/ for the JSON specs.
Because the last two options are not a valid json
- There should be no comma after last element
- a
[should match a](array) and a{should match a}(object)