Repository: internetarchive/openlibrary

Issue:
/openlibrary/openlibrary/templates/lists/widget.html: error in processing template: TypeError: Object of type Nothing is not JSON serializable (falling back to default template)
Patron is reporting the following error:
`/openlibrary/openlibrary/templates/lists/widget.html: error in processing template: TypeError: Object of type Nothing is not JSON serializable (falling back to default template)`

### Evidence / Screenshot (if possible)

### Relevant url?
https://openlibrary.org/works/OL24171550W/Kelebihan_Amalan_Bulan_Rejab_Sya%E2%80%99ban_Ramadhan

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Go to ... https://openlibrary.org/works/OL24171550W/Kelebihan_Amalan_Bulan_Rejab_Sya%E2%80%99ban_Ramadhan
2. Do ... view error.

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual: 
* Expected: 

### Details

- **Logged in (Y/N)?** 
- **Browser type/version?** 
- **Operating system?** 
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->



Discussion:
Unable to reproduce this issue on dev: https://dev.openlibrary.org/works/OL24171550W/Kelebihan_Amalan_Bulan_Rejab_Sya%E2%80%99ban_Ramadhan
https://dev.openlibrary.org/status shows that it is running legacy Python 2.7.6
https://openlibrary.org/status shows that it is running Python 3.8.6
Start up a local instance
```
docker exec -it openlibrary_web_1 /bin/bash
python3 scripts/copydocs.py /works/OL24171550W
http://localhost:8080/works/OL24171550W/Kelebihan_Amalan_Bulan_Rejab_Sya’ban_Ramadhan?debug=true
```
Note sure how many records this is affecting? Seems not super prevalent, setting to p3.
Looking at the edition json, it seems possible that the title:"Kelebihan Amalan Bulan Rejab, Sya\u2019ban & Ramadhan" is somehow problematic. The author name containing "Alias" is also suggestive, but not all the works by that author show the error.
https://openlibrary.org/works/OL24171550W/Kelebihan_Amalan_Bulan_Rejab_Sya%E2%80%99ban_Ramadhan?debug=true  Looking down into the URL with `?debug=true` this looks to be `covers` related...
I notice that see the covers error only when logged in, but see the widgets error twice, whether logged in or out.
Hmm, this looks like it is the same Infogami `Nothing` I struggled with here https://github.com/internetarchive/infogami/issues/148
It doesn't quite behave like `None` , and a list of results containing it _looks_ empty like `[]` , but is not equal to `[]`

Resolving patch:
diff --git a/openlibrary/core/helpers.py b/openlibrary/core/helpers.py
--- a/openlibrary/core/helpers.py
+++ b/openlibrary/core/helpers.py
@@ -1,16 +1,10 @@
 """Generic helper functions to use in the templates and the webapp.
 """
 import web
-from datetime import datetime
+import json
 import re
-
-import six
-from six.moves.urllib.parse import urlsplit
-
-if six.PY2:  # See #4525 json.dump(indent) MUST be an int on PY2
-    import simplejson as json
-else:
-    import json
+from datetime import datetime
+from urllib.parse import urlsplit
 
 import babel
 import babel.core
@@ -29,7 +23,7 @@
     BeautifulSoup = None
 
 from infogami import config
-
+from infogami.infobase.client import Nothing
 # handy utility to parse ISO date strings
 from infogami.infobase.utils import parse_datetime
 from infogami.utils.view import safeint
@@ -101,7 +95,7 @@ def get_nofollow(name, event):
 def json_encode(d, **kw):
     """Same as json.dumps.
     """
-    return json.dumps(d, **kw)
+    return json.dumps([] if isinstance(d, Nothing) else d, **kw)
 
 
 def safesort(iterable, key=None, reverse=False):
@@ -184,7 +178,7 @@ def commify(number, lang=None):
         lang = lang or web.ctx.get("lang") or "en"
         return babel.numbers.format_number(int(number), lang)
     except:
-        return six.text_type(number)
+        return str(number)
 
 
 def truncate(text, limit):
@@ -303,5 +297,5 @@ def _get_helpers():
     return web.storage((k, _globals[k]) for k in __all__)
 
 
-## This must be at the end of this module
+# This must be at the end of this module
 helpers = _get_helpers()


Test patch: