Функция `return list` вызывает ошибку. Как можно это исправить?

Привет всем! У меня есть функция, которая выводит список, и она работает корректно. Однако иногда возникает ошибка: <br/> <pre><code>TypeError: string indices must be integers, not 'str'</code></pre> <br/> Как я могу устранить эту ошибку? <br/> <pre><code class="python">def get_user_guilds():
    oauth2_token = session.get('oauth2_token')
    discord = make_session(token=oauth2_token)
    guilds = discord.get(API_BASE_URL + '/users/@me/guilds').json()

    return guilds


def get_user_managed_servers(guilds):
    return list(
        filter(
            lambda g: (g['owner'] is True) or
            bool((int(g['permissions']) &gt;&gt; 5) &amp; 1),
            guilds)
    )

@app.route('/servers')
def servers():
    guilds = get_user_guilds()
    user_servers = get_user_managed_servers(guilds)
    return render_template('select-server.html', user_servers=user_servers)</code></pre>
  • 22 января 2025 г. 7:14
Ответы на вопрос 3
Ошибка, которую вы получаете — `TypeError: string indices must be integers, not 'str'` — указывает на то, что вы пытаетесь обратиться к элементам строки как к элементам словаря. Это может случиться, если `guilds`, передаваемые в функцию `get_user_managed_servers`, не является списком объектов, содержащих ключи, к которым вы обращаетесь. 

Ваша функция `get_user_guilds` возвращает результат, получаемый в методе `json()`, и если этот результат по какой-то причине окажется строкой (например, если API вернул ошибку), попытка вас обратиться к элементам этой строки приведёт к ошибке.

Вот несколько шагов, которые помогут вам справиться с этой проблемой:

1. **Проверьте ответ от API**: Убедитесь, что вы получаете корректный ответ от API. Это можно сделать, проверив статус-код ответа перед тем, как вызывать `json()`. 

2. **Обработка ошибок**: Добавьте обработку ошибок, чтобы отслеживать и правильно обрабатывать случаи, когда API возвращает ошибку или данные в неожиданном формате.

Вот как можно переписать функцию `get_user_guilds` с обработкой ошибок:

```python
def get_user_guilds():
    oauth2_token = session.get('oauth2_token')
    discord = make_session(token=oauth2_token)
    response = discord.get(API_BASE_URL + '/users/@me/guilds')

    # Проверка на успешный ответ
    if response.status_code != 200:
        # Обработка ошибки, например, логируем и возвращаем пустой список
        print(f"Error fetching guilds: {response.status_code} - {response.text}")
        return []

    guilds = response.json()

    # Дополнительно проверяем, что полученные данные являются списком
    if not isinstance(guilds, list):
        print(f"Expected list of guilds but got: {type(guilds)}")
        return []

    return guilds
```

Теперь, если сервер вернёт ошибку, или если формат ответа будет неожиданным, ваша функция не вызовет дальнейших ошибок и вернёт пустой список.

Также стоит добавить проверку внутри функции `get_user_managed_servers`, чтобы убедиться, что каждый элемент — это словарь с нужными ключами:

```python
def get_user_managed_servers(guilds):
    if not isinstance(guilds, list):
        return []

    return list(
        filter(
            lambda g: isinstance(g, dict) and (
                (g.get('owner') is True) or
                bool((int(g.get('permissions', 0)) >> 5) & 1)),
            guilds)
    )
```

В результате, ваше приложение сможет устойчиво работать даже в случае, если API вернет ошибку или данные будут в неправильном формате.
А дебажить кто будет, а логгирование ошибок кто будет вести? Походу guilds не всегда является списком словарей. 
Все работает корректно, но иногда может появиться ошибка:
TypeError: string indices must be integers, not 'str'

Хорошо бы полный traceback ошибки (втч. номера строк) видеть.
Потому что вместо словаря приходит строка, где вы пытаетесь обратиться по строковому индексу. 
Где именно - разбирайтесь, в вопросе информации недостаточно, но вероятно в
filter(
            lambda g: (g['owner'] is True) or
            bool((int(g['permissions']) >> 5) & 1),
            guilds)

Читайте что может возвращать метод discord.get()
Похожие вопросы