From a21d01548793b4f065051fd5bd693311b0618986 Mon Sep 17 00:00:00 2001 From: MeloleM Date: Sun, 16 Aug 2026 01:57:02 +0300 Subject: [PATCH] fix: stop swallowing startup errors and fix fresh-install crashes Client.Save() called exit(0), and Save() runs from close(), which discord.py calls in run()'s finally block. Any exception raised during login or connect was therefore replaced by SystemExit before the traceback could print, so every startup failure looked identical: logging in using static token . . . Saved Userdata Successfully ! --- Client disconnected --- with no indication of what actually went wrong. Removing exit(0) lets close() finish normally and the original exception propagate. Also: - Load a .env file when python-dotenv is available, and print a clear message instead of a TypeError when econtoken is unset. - LoadUserDict() called os.mknod(), which doesn't exist on Windows, and then pickle.load() on the empty file it created. Treat a missing or empty save file as an empty user_dict instead. - Document the privileged gateway intents in the README. Intents.all() requires all three, and skipping them raises PrivilegedIntentsRequired. --- README.md | 17 ++++++++++++++++- main.py | 16 +++++++++++++++- saveload/saveload.py | 5 +++-- singletons.py | 2 -- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d48348c..5ae4b93 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,9 @@ python --version - Install the required dependencies: ```bash -pip install discord +pip install discord python-dotenv ``` +(`python-dotenv` is optional, it only lets you keep your token in a `.env` file instead of a system environment variable.) ## Discord Application Deployment @@ -98,6 +99,12 @@ pip install discord 8. You may use the Generated URL to invite your bot into your servers. +9. Go to the `Bot` section and scroll down to `Privileged Gateway Intents`, then turn **all three** of them on: + `Presence Intent`, `Server Members Intent` and `Message Content Intent`. + + EconBot reads normal chat messages to catch its `!` commands, and Discord keeps that behind a switch you have to flip yourself. + If you skip this step the bot will crash on startup with `PrivilegedIntentsRequired`. + --- Token Setup & Environment Variable Setup @@ -122,6 +129,14 @@ pip install discord [Linux (Ubuntu)](https://www.youtube.com/watch?v=Y6_7xaxkPik) +_Alternatively_, if you installed `python-dotenv`, you can create a file named `.env` next to `main.py` containing: + +``` +econtoken=YOUR TOKEN HERE +``` + +`.env` is already in `.gitignore`, so your token won't be committed by accident. + _Alternatively_ you can just directly paste the bot token into the code; however, this is __not recommended__. - To do this, go to the file `main.py` and on the last line you should see diff --git a/main.py b/main.py index 2351e7f..8e7fd88 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,13 @@ # Libraries import discord import os +import sys + +try: + from dotenv import load_dotenv + load_dotenv() # Loads a local .env file if one exists, system env vars still take priority. +except ImportError: + pass # python-dotenv is optional, a system environment variable works just as well. import singletons import constants @@ -208,4 +215,11 @@ async def InvokeEcon(message : discord.Message) -> None: await message.reply(embed=embed) -singletons.client.run(os.getenv("econtoken")) +token = os.getenv("econtoken") + +if not token: + singletons.print_colored("[ NO TOKEN FOUND ! ]", "red") + print("Set an environment variable named 'econtoken', or put econtoken= in a .env file next to main.py.") + sys.exit(1) + +singletons.client.run(token) diff --git a/saveload/saveload.py b/saveload/saveload.py index 81fb9bf..4b80141 100644 --- a/saveload/saveload.py +++ b/saveload/saveload.py @@ -52,8 +52,9 @@ async def SaveUserDict() -> None: print(f"Error: {err}") def LoadUserDict() -> bool: - if not os.path.exists(save_path): - os.mknod(save_path) + if not os.path.exists(save_path) or os.path.getsize(save_path) == 0: + singletons.user_dict = {} # Fresh install, nothing saved yet. SaveUserDict creates the file later. + return True with open(save_path,'rb') as file: singletons.user_dict = pickle.load(file=file) return True diff --git a/singletons.py b/singletons.py index db348ae..0e9ff6c 100644 --- a/singletons.py +++ b/singletons.py @@ -27,8 +27,6 @@ async def Save(self): print_colored("--- Client disconnected ---", "red") - exit(0) - async def close(self): # Perform cleanup before closing await self.async_cleanup()