diff --git a/core/economy/gambling.py b/core/economy/gambling.py index c89a72d..1ebe713 100644 --- a/core/economy/gambling.py +++ b/core/economy/gambling.py @@ -248,7 +248,12 @@ async def do_blackjack_bet(user_id: int, bet: int) -> dict: if user["balance"] < bet: return {"ok": False, "reason": "insufficient", "balance": user["balance"]} user["balance"] -= bet - await _commit(user_id, user) + try: + await _commit(user_id, user) + except DatabaseError: + # Deduction never persisted, so the player was not charged - report it + # instead of raising through the interaction handler. + return {"ok": False, "reason": "db_error"} return {"ok": True, "balance": user["balance"]} diff --git a/docs/DEV_NOTES.md b/docs/DEV_NOTES.md index c00a2cb..af08b3b 100644 --- a/docs/DEV_NOTES.md +++ b/docs/DEV_NOTES.md @@ -58,7 +58,7 @@ Pick the `commands/economy_*_commands.py` file that matches the new command's ca Checklist - do all of these, in order: 1. **`core/economy/.py`** (e.g. `income.py`, `gambling.py`, `fishing.py`) - add the `do_` async function with cooldown check, logic, `_commit`, and `_txn` logging (`get_user`/`_commit`/`_txn` live in `store.py`) -2. **`core/economy/store.py`** - add the cooldown to `COOLDOWNS` dict if it has one +2. **`core/economy/store.py`** - add the cooldown to `COOLDOWNS` dict if it has one. Compute the effective cooldown in `do_` with `effective_cooldown("", user["items"])` rather than an inline `timedelta(...) if item in items else ...` 3. **`core/economy/levels.py`** - add the EXP reward to `EXP_REWARDS` dict 4. **`strings/commands.py` `CMD`** - add the slash command description 5. **`strings/commands.py` `OPT`** - add any parameter descriptions @@ -66,11 +66,11 @@ Checklist - do all of these, in order: 7. **`strings/common.py` `ERR`** - add any error messages (banned, cooldown uses `CD_MSG`, jailed uses `CD_MSG["jailed"]`) 8. **`strings/common.py` `CD_MSG`** - add cooldown message if command has a cooldown 9. **`strings/commands.py` `HELP_CATEGORIES["tipibot"]["fields"]`** - add the command to the help embed -10. **`commands/economy__commands.py`** - inside `register_*_commands`, add `@tree.command(name="", ...)` `cmd_`; handle all `res["reason"]` cases +10. **`commands/economy__commands.py`** - inside `register_*_commands`, add `@tree.command(name="", ...)` `cmd_`; handle all `res["reason"]` cases. If `do_` can return `db_error` (any function that calls `get_user`/`_commit`), handle it first in the failure block with `await reply_db_error(interaction); return` (import from `._replies`) - otherwise a DB outage hangs the deferred interaction or shows a misleading message 11. **`commands/economy__commands.py`** - call `maybe_remind(user_id, "")` if the command has a cooldown and reminders make sense (the helper is passed in via the `register_*` signature) 12. **`commands/economy__commands.py`** - call `await award_exp(interaction, economy.EXP_REWARDS[""])` on success 13. **`strings/common.py` `REMINDER_OPTS`** - add a reminder option if the command needs one -14. **`bot.py` `_maybe_remind`** - if the command has an item-modified cooldown, add an `elif` branch (this helper still lives in `bot.py` and is shared across all command modules) +14. **`core/economy/store.py` `ITEM_COOLDOWNS`** - if an item shortens the command's cooldown, add `"": ("", timedelta(...))` here. This is the single source of truth: `effective_cooldown` (used by `do_`), `_maybe_remind`, and `_restore_reminders` all read it, so you no longer edit the reminder helpers by hand ---