fix: fail loud on missing emoji dir, stem collisions, and corrupt images
refresh() previously treated a missing assets/emojis folder (wrong cwd,
missing WorkingDirectory=/WORKDIR) as an empty one, silently deleting
every application emoji on the app every restart with no signal and no
way back (recreated emojis get new IDs). _scan_folder now raises
DPYAppEmojisError naming the absent path instead; a present-but-empty
folder still mirrors as before.
Two files sharing a name stem across extensions (check.png + check.gif)
used to silently collapse to one synced emoji via last-write-wins,
breaking the documented delete+re-add replace workflow with no error.
_scan_folder now raises DPYAppEmojisError naming both colliding files.
A valid extension with unrecognized magic bytes (truncated download,
mismatched format) made discord.py raise an anonymous
ValueError('Unsupported image type given') from create_application_emoji,
which the lib's (Forbidden, HTTPException) catch didn't cover, leaving
no way to tell which file in a large folder was broken. _scan_folder now
pre-flights the same magic-byte check discord.py itself uses and raises
ValueError naming the offending file before any create is attempted.
Also collapses the redundant Forbidden member in the create/delete except
clauses (Forbidden already subclasses HTTPException); log-then-raise
behavior is unchanged.
Bump 0.1.0 -> 0.1.1.
Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
@@ -34,6 +34,12 @@ appmojis.list() # ["success_mark", ...]
|
||||
Call `refresh()` at startup, or from a command, to re-sync on demand — the lib adds no
|
||||
commands of its own.
|
||||
|
||||
A **missing** `assets/emojis` folder is not the same as an **empty** one: if the folder
|
||||
doesn't exist (wrong cwd, missing `WorkingDirectory=`/`WORKDIR`), `refresh()` raises
|
||||
`DPYAppEmojisError` naming the path instead of mirroring an empty desired set — which would
|
||||
otherwise delete every application emoji on the next restart. An empty-but-present folder is
|
||||
still honored as "delete everything."
|
||||
|
||||
## Dot-access vs `emoji()`
|
||||
|
||||
`self.get` is a namespace whose attribute lookup returns the emoji by name. It lives apart
|
||||
@@ -60,11 +66,22 @@ targets **`discord.py>=2.5`**.
|
||||
## Contract (fail-loud)
|
||||
|
||||
The module docstring (`help(dpy_appemojis)` / IDE hover) is the source of truth. Nothing is
|
||||
swallowed: an invalid emoji name from a bad filename or an oversized file raises `ValueError`
|
||||
naming the file; exceeding the 2000 cap raises `DPYAppEmojisError` **before** any create; a
|
||||
discord API error (`Forbidden` / `HTTPException`) propagates **unwrapped** so a partial sync
|
||||
never hides behind a silent success. `emoji(name)` / `get.<name>` for a name that wasn't
|
||||
synced raise `KeyError` / `AttributeError` (call `refresh()` first).
|
||||
swallowed:
|
||||
|
||||
- an invalid emoji name from a bad filename, an oversized file, or a file whose bytes aren't
|
||||
a recognized PNG/JPEG/GIF/WEBP image (corrupt, truncated, or mismatched extension) raises
|
||||
`ValueError` naming the file
|
||||
- two files sharing a name stem across extensions (e.g. `check.png` and `check.gif`) raise
|
||||
`DPYAppEmojisError` naming **both** files, instead of silently syncing one and dropping the
|
||||
other
|
||||
- a missing `assets/emojis` folder raises `DPYAppEmojisError` naming the path (see above)
|
||||
rather than mirroring an empty set
|
||||
- exceeding the 2000 cap raises `DPYAppEmojisError` **before** any create
|
||||
- a discord API error (`HTTPException`, which covers `Forbidden`) propagates **unwrapped** so
|
||||
a partial sync never hides behind a silent success
|
||||
|
||||
`emoji(name)` / `get.<name>` for a name that wasn't synced raise `KeyError` / `AttributeError`
|
||||
(call `refresh()` first).
|
||||
|
||||
## Versioning
|
||||
|
||||
|
||||
Reference in New Issue
Block a user