Skip to content

fix(worker): graceful skip when Servers or Messages data is absent#83

Merged
Androz2091 merged 1 commit intomainfrom
fix/optional-servers-messages
May 7, 2026
Merged

fix(worker): graceful skip when Servers or Messages data is absent#83
Androz2091 merged 1 commit intomainfrom
fix/optional-servers-messages

Conversation

@Androz2091
Copy link
Copy Markdown
Member

Same fallback bug that PR #82 fixed for the analytics path, but for Servers and Messages.

A user reported UNKNOWN_ERROR for package `4aa23a2a6ea2f52ba9016a723143b792`. CloudWatch:

```
File "/app/tasks.py", line 466, in read_analytics_file
server_content = zip.open(server_path)
KeyError: "There is no item named 'Servers/index.json' in the archive"
```

The user un-ticked Servers in Discord's data-request form. The old code:

```py
servers_root = find_servers_root(namelist)
if not servers_root:
server_path = 'Servers/index.json' # blind fallback
if server_path not in namelist and 'servers/index.json' in namelist:
server_path = 'servers/index.json'
else:
server_path = f'{servers_root}/index.json'

server_content = zip.open(server_path) # KeyError if neither exists
```

If `find_servers_root` returns None and neither lowercase fallback matches the existence check (the existing logic only swaps to lowercase if the canonical path isn't present and lowercase is — so if both are absent, `server_path` ends up as the literal `'Servers/index.json'`), `zip.open` blows up.

Same exact pattern in the Messages block right below.

Fix

Make the path resolution defensive — only assign a path that actually exists in `zip.namelist()`; if nothing matches, set None and skip the read block, marking `is_partial=True`. The rest of the worker tolerates empty servers / empty channels lists (the message-CSV walker filters by namelist, so it processes 0 channels naturally).

Possible outcomes after this:

Servers? Messages? Result
Normal full package
DMs / friends / payments / per-channel stats; server stats N/A. `is_partial=true`
Server list / friends / payments; channel and DM stats N/A. `is_partial=true`
Profile + friends + payments only. `is_partial=true`

Test plan

  • Merge → CI deploys.
  • Re-submit `4aa23a2a6ea2f52ba9016a723143b792` — expect PROCESSED with `is_partial=true`.
  • No regression on packages with both folders present (most common case).

A user reported UNKNOWN_ERROR for package 4aa23a2a6ea2f52ba9016a723143b792.
Traceback:

  File "/app/tasks.py", line 466, in read_analytics_file
    server_content = zip.open(server_path)
  KeyError: "There is no item named 'Servers/index.json' in the archive"

Same fallback bug that PR #82 fixed for the analytics path: when the
discovered root is None, the old code blindly assigned the canonical
literal 'Servers/index.json' (resp. 'Messages/index.json') and let
zip.open KeyError if that file isn't actually in the archive. That
happens when the user un-ticks 'Servers' (or 'Messages') in Discord's
data-request form.

Fix: only assign a path that actually exists in zip.namelist(); if
nothing matches, set it to None and skip the read block, marking
is_partial=True. The rest of the worker copes with empty servers /
empty channels lists (the message-CSV walker filters by
namelist anyway, so it just processes 0 channels).

After this:
- No Servers folder → no guild-scoped stats but DMs/friends/payments OK
- No Messages folder → no channel-scoped stats but server list/payments OK
- Both missing → minimal package, but no crash
@Androz2091 Androz2091 merged commit c558b90 into main May 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant