Solve Raise JSONDecodeError(Expecting Value, S, err.value) From None in Python
When working with URLs and APIs in Pythons, you often have to use the
urllib
and
json
libraries. More importantly, the
json
library helps with processing JSON data which is the default way to transfer data, especially with APIs.
Within the
json
library, there is a method,
loads()
, that returns the
JSONDecodeError
error. In this article, we will discuss how to resolve such errors and deal with them appropriately.
Use
try
to Solve
raise JSONDecodeError("Expecting value", s, err.value) from None
in Python
Before dealing with JSON, we often had to receive data via the
urllib
package. However, when working with the
urllib package
, it is important to understand how to import such a package into your code as it could result in errors.
For us to make use of the
urllib
package, we have to import it. Often, people might import it as below.
import urllib
queryString = { 'name' : 'Jhon', 'age' : '18'}
urllib.parse.urlencode(queryString)
The output of the code above will give an
AttributeError
:
Traceback (most recent call last):
File "c:\Users\akinl\Documents\HTML\python\test.py", line 3, in <module>
urllib.parse.urlencode(queryString)
AttributeError: module 'urllib' has no attribute 'parse'
The correct way to import the
urllib
can be seen below.
import urllib.parse
queryString = {'name': 'Jhon', 'age': '18'}
urllib.parse.urlencode(queryString)
Alternatively, you can use the
as
keyword and your alias (often shorter) to make it easier to write your Python code.
import urllib.parse as urlp
queryString = {'name': 'Jhon', 'age': '18'}
urlp.urlencode(queryString)
All of the above works for
request
,
error
, and
robotparser
:
import urllib.request
import urllib.error
import urllib.robotparser
With these common errors out of the way, we can deal further with the function that often works with the
urllib
library when working with URLs that throws the
JSONDecodeError
error, as seen earlier, which is the
json.load()
function.
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The
load()
method parses valid JSON string that it receives as an argument and converts it into a Python dictionary for manipulation. The error message shows that it expected a JSON value but did not receive one.
That means your code did not parse JSON string or parse an empty string to the
load()
method. A quick code snippet can easily verify this.
import json
data = ""
js = json.loads(data)
The output of the code:
Traceback (most recent call last):
File "c:\Users\akinl\Documents\python\texts.py", line 4, in <module>
js = json.loads(data)
File "C:\Python310\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Python310\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python310\lib\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)
The same error message is present, and we can ascertain that the error came from an empty string argument.
For a more detailed example, let us try to access a Google Map API and collect user location, e.g., US or NG, but it does not return any value.
import urllib.parse
import urllib.request
import json
googleURL = 'http://maps.googleapis.com/maps/api/geocode/json?'
while True:
address = input('Enter location: ')
if address == "exit":
break
if len(address) < 1:
break
url = googleURL + urllib.parse.urlencode({'sensor': 'false',
'address': address})
print('Retrieving', url)
uReq = urllib.request.urlopen(url)
data = uReq.read()
print('Returned', len(data), 'characters')
js = json.loads(data)
print(js)
The output of the code:
Traceback (most recent call last):
File "C:\Users\akinl\Documents\html\python\jsonArt.py", line 18, in <module>
js = json.loads(str(data))
File "C:\Python310\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Python310\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python310\lib\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)
We obtained the same error. However, to catch such errors and prevent breakdown, we can use the
try/except
logic to safeguard our code.
Therefore, if the API does not return any JSON value at a point of request, we can return another expression and not an error.
The above code becomes:
import urllib.parse
import urllib.request
import json
googleURL = 'http://maps.googleapis.com/maps/api/geocode/json?'
while True:
address = input('Enter location: ')
if address == "exit":
break
if len(address) < 1:
break
url = googleURL + urllib.parse.urlencode({'sensor': 'false',
'address': address})
print('Retrieving', url)
uReq = urllib.request.urlopen(url)
data = uReq.read()
print('Returned', len(data), 'characters')
try:
js = json.loads(str(data))
except:
print("no json returned")