简体   繁体   中英

How can I handle KeyError in python for my example

Im making a telegram bot using Python and Firebase. I get stucked at a KeyError:

2021-02-12 12:39:38,687 - telegram.ext.dispatcher - ERROR - No error handlers are registered, logging exception.
Traceback (most recent call last):
  File "C:\Users\Lil-Dredd\PycharmProjects\TelegramBot\venv\lib\site-packages\telegram\ext\dispatcher.py", line 442, in process_update
    handler.handle_update(update, self, check, context)
  File "C:\Users\Lil-Dredd\PycharmProjects\TelegramBot\venv\lib\site-packages\telegram\ext\conversationhandler.py", line 549, in handle_update
    new_state = handler.handle_update(update, dispatcher, check_result, context)
  File "C:\Users\Lil-Dredd\PycharmProjects\TelegramBot\venv\lib\site-packages\telegram\ext\handler.py", line 160, in handle_update
    return self.callback(update, context)
  File "C:\Users\Lil-Dredd\PycharmProjects\TelegramBot\bot.py", line 61, in start
    print(user.val()["chat_id"])
KeyError: 'chat_id'

Here is my code:

def start(update: Update, context: CallbackContext) -> int:
    global PauseKey, PauseStart, PauseState, PauseAllKey
    timenow = datetime.now()
    auth = firebase.auth()
    userx = auth.sign_in_with_email_and_password('drux@mail.com', '12345678')
    db = firebase.database()
    chat_user_client = update.message.from_user.username
    all_users = db.child("users").get()
    user_status = "none"

    for user in all_users.each():
        print(user.val()["chat_id"])
        if user.val()["chat_id"] == update.message.chat_id:
            user_status = "exist"
            userKey = user.key()
            break
    print(user_status)
    if user_status == "exist":
        text_back = "You was logged in, Welcome back "
    else:
        data = {"name": chat_user_client, "chat_id": update.message.chat_id}
        date = {"date": datetime.today().strftime('%Y-%m-%d-%H:%M:%S')}
        userKey= db.child("users").push(data)
        userKey = userKey.val()
        text_back = "User was create"


    update.message.reply_text(
    f'{text_back}{chat_user_client}',
    reply_markup=markup2
    )


    return CHOOSING

Error Block:

for user in all_users.each():
        print(user.val()["chat_id"])
        if user.val()["chat_id"] == update.message.chat_id:
            user_status = "exist"
            userKey = user.key()
            break

and this print print(user.val()["chat_id"]) show 690953230 in console. Which is a correct chat id that is stocked in my firebase.

I tried to used await with asyncio library, for this line:

all_users = db.child("users").get()
async def start()
...
all_user = await db.child("users").get()
...

With async and await error was leaving but code didnt do expected stuff.

The code should do the following: browse all users data and check if user_chat_id is already in database. If chat_id is already in database then user exist and Im working with his table key. If user dosnt exist im creating his table and take his user key.

I get stucked for hours with this error and cant handle it on my own, please help.

Edit

Now I found that if my user exist the code is working fine. I mean if my chat_id is already in database i dont get any errors, if im deleting im data from database im getting keyError

I suggest you to use get while getting element from dictionary; because while dict["key"] gives error, dict.get("key") does not give error when the key doesn't exist. My suggestion is to update the error block as:

for user in all_users.each():
    chat_id = user.val().get("chat_id")
    if chat_id and  chat_id == update.message.chat_id:
        user_status = "exist"
        userKey = user.key()
        break

Furthermore, you should do some refactoring to enhance readability. For example in above block of code following assignment looks redundant:

userKey = user.key()

You can also extract user existance checking as another method:

def user_exists(all_users, msg_chat_id):
    for user in all_users.each():
        chat_id = user.val().get("chat_id")
        if chat_id and  chat_id == msg_chat_id:
            return true
    return false

Then use it in start method as:

def start(update: Update, context: CallbackContext) -> int:
    global PauseKey, PauseStart, PauseState, PauseAllKey
    timenow = datetime.now()
    auth = firebase.auth()
    userx = auth.sign_in_with_email_and_password('drux@mail.com', '12345678')
    db = firebase.database()
    chat_user_client = update.message.from_user.username
    all_users = db.child("users").get()

    if user_exists(all_users, update.message.chat_id):
        text_back = "You was logged in, Welcome back "
    else:
        data = {"name": chat_user_client, "chat_id": update.message.chat_id}
        date = {"date": datetime.today().strftime('%Y-%m-%d-%H:%M:%S')}
        userKey= db.child("users").push(data)
        userKey = userKey.val()
        text_back = "User was create"


    update.message.reply_text(
    f'{text_back}{chat_user_client}',
    reply_markup=markup2
    )


    return CHOOSING

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM