Функция `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 не всегда является списком словарей. <br/> <blockquote>Все работает корректно, но иногда может появиться ошибка:<br/>
TypeError: string indices must be integers, not 'str'</blockquote> <br/> Хорошо бы полный traceback ошибки (втч. номера строк) видеть.
Потому что вместо словаря приходит строка, где вы пытаетесь обратиться по строковому индексу. <br/> Где именно - разбирайтесь, в вопросе информации недостаточно, но вероятно в <pre><code>filter(
            lambda g: (g['owner'] is True) or
            bool((int(g['permissions']) &gt;&gt; 5) &amp; 1),
            guilds)</code></pre> <br/> Читайте что может возвращать метод <code>discord.get()</code>
Похожие вопросы