toconnell / kdm-manager

An interactive campaign manager for the game "Monster", by Kingdom Death. Development blog and release notes at https://blog.kdm-manager.com This project has no affiliation with Kingdom Death and is a totally independent, fan-maintained project.
http://kdm-manager.com
Other
26 stars 11 forks source link

/settlement/get_summary/$oid call fails #537

Closed toconnell closed 4 years ago

toconnell commented 4 years ago

From Twitter:

Anton @Antononon 1d @KdmManager yo, our settlement has stopped working halfway through the evening. It says Retrieving Settlement 2/4 at the bottom and doesn't get any further. Have I broken something?

From the prod API logs:

User OID: 5d88dec26515935202c7a5a8 Method: GET URL: http://api.kdm-manager.com/settlement/get_summary/5de7e88365159353a8159b92

JSON: None

Traceback (most recent call last):
File "/home/toconnell/kdm-manager-api/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
 rv = self.dispatch_request()
File "/home/toconnell/kdm-manager-api/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
 return self.view_functions[rule.endpoint](**req.view_args)
File "/home/toconnell/kdm-manager-api/app/utils/crossdomain.py", line 56, in wrapped_function
 resp = flask.make_response(func(*args, **kwargs))
File "/home/toconnell/kdm-manager-api/app/routes.py", line 454, in collection_action
 asset_object = assets.get_user_asset(collection, asset_id)
File "/home/toconnell/kdm-manager-api/app/assets/__init__.py", line 86, in get_user_asset
 return settlements.Settlement(_id=asset_id)
File "/home/toconnell/kdm-manager-api/app/utils/__init__.py", line 289, in not_timed
 return method(*args, **kwargs)
File "/home/toconnell/kdm-manager-api/app/models/settlements.py", line 140, in __init__
 self.normalize()
File "/home/toconnell/kdm-manager-api/app/models/settlements.py", line 347, in normalize
 self.baseline()
File "/home/toconnell/kdm-manager-api/app/models/settlements.py", line 3706, in baseline
 self.settlement[attrib] = int(self.settlement[attrib])
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
toconnell commented 4 years ago

Print debugging shows that it's population throwing the error. Legacy webapp admin asset dump confirms:

population <type 'NoneType'> |None|

toconnell commented 4 years ago
diff --git a/app/models/settlements.py b/app/models/settlements.py
index 6a463d7..9559689 100644
--- a/app/models/settlements.py
+++ b/app/models/settlements.py
@@ -3703,7 +3703,13 @@ class Settlement(models.UserAsset):
         # Duck Typing!

         for attrib in ['survival_limit', 'population', 'death_count']:
-            self.settlement[attrib] = int(self.settlement[attrib])
+            try:
+                self.settlement[attrib] = int(self.settlement[attrib])
+            except TypeError:
+                err = 'Illegal %s value: %s! Resetting to zero!'
+                self.log_event(err % (attrib, self.settlement[attrib]))
+                self.settlement[attrib] = 0
+                self.perform_save = True
toconnell commented 4 years ago

committed and deployed.