Closed toconnell closed 2 years ago
It looks like this is actually bombing out during settlement load:
[2021-09-15 08:56:43] DEBUG: PERSEO [M] (613e02cd2469bec8182c676a) saving during 'set_attribute' action! Starting post-process...
[2021-09-15 08:56:43] WARNING: PERSEO [M] (613e02cd2469bec8182c676a) Weapon mastery reached, but A&I not present! Adding A&I...
[2021-09-15 08:56:43] ERROR: Unhandled exception in log_event() method!args: (), kwargs: {'action': 'add', 'key': 'epithets', 'value': 'Bow Master'}
Traceback (most recent call last):
File "/home/toconnell/kdm-manager-api/app/models/__init__.py", line 122, in wrapper
return log_event_call(self, *args, **kwargs)
File "/home/toconnell/kdm-manager-api/app/models/__init__.py", line 1484, in log_event
"settlement_id": self.settlement_id,
AttributeError: 'Survivor' object has no attribute 'settlement_id'
Alright, so first up, let's mitigate the bad code in semantic logging:
diff --git a/app/models/__init__.py b/app/models/__init__.py
index c3d411e..378cd90 100644
--- a/app/models/__init__.py
+++ b/app/models/__init__.py
@@ -1481,7 +1481,8 @@ class UserAsset(object):
"created_on": datetime.now(),
'created_by': created_by,
'created_by_email': created_by_email,
- "settlement_id": self.settlement_id,
+# "settlement_id": self.settlement_id,
+ "settlement_id": getattr(self, 'settlement_id', None),
"ly": self.get_current_ly(),
'event_type': event_type,
'event': msg,
This next thing we're hitting:
[2021-09-15 09:08:38] ERROR: Could not load _id '613e02a55c3654f1e4d59a60' from settlements!
[2021-09-15 09:08:38] ERROR: 'Settlement' object has no attribute 'Innovations'
This only happens when a settlement doesn't have a chance to call init_asset_collections()
(or, I guess, if that fails).
So what's happening here, is a survivor has a weapon mastery (based on points) and we're trying to add it to the settlement's innovations and exploding:
File "/home/toconnell/kdm-manager-api/app/models/survivors/__init__.py", line 254, in post_process
self.add_game_asset("abilities_and_impairments", w_dict['master_ai'], save=False)
File "/home/toconnell/kdm-manager-api/app/models/survivors/__init__.py", line 1030, in add_game_asset
self.Settlement.add_innovation(asset_dict["handle"])
File "/home/toconnell/kdm-manager-api/app/models/settlements.py", line 1085, in add_innovation
i_dict = self.Innovations.get_asset(i_handle)
...which looks like the survivor's (not the settlement's) self.Settlement isn't being initialized correctly?
Yeah, OK: looks like survivors are calling the base class load() on init, rather than their private version.
I think I cracked the case.
For some idiotic reason, the Survivor object was initializing by calling its base class init() method directly:
- models.UserAsset.__init__(self, *args, **kwargs)
Which should be using super()
, since we're using new-style classes now:
+ super().__init__(self, *args, **kwargs)
Alright, I figured it out. The problem is that the _set_lastaccessed() method fires whenever a survivor object is initialized; problem is, the private (not the base class, but the child class) save() method for the Survivor object kicks off the post-process code, which expects an initialized object, not one that is in the process of being initialized.
- if hasattr(request, 'action') and request.action in post_process_routes:
+
+ # never post-process an uninitialized Survivor:
+ if getattr(self, 'Settlement', None) is None:
+ bypass_post_process = True
+
+ if (
+ not bypass_post_process and
+ hasattr(request, 'action') and
+ request.action in post_process_routes
+ ):
self.post_process()
The first one came through like this:
But this settlement has dozens of these: