dronefly-garden / dronefly

Red Discord Bot V3 cogs for naturalists.
Other
16 stars 3 forks source link

taxa: Handle broken API responses that are valid JSON #170

Open synrg opened 2 years ago

synrg commented 2 years ago

The error handling for API calls that return valid JSON, but don't contain expected fields in the response leaves something to be desired. For example, in inat.py in make_taxa_embed, where a taxon has already been retrieved, but the full taxon record is needed to get full means & status info:

        full_record = (
            await self.api.get_taxa(
                ctx, taxon.id, preferred_place_id=preferred_place_id
            )
        )["results"][0]
        full_taxon = Taxon.from_json(full_record)

There's no exception handling around this, potentially leading to a traceback like this:

[2022-08-08 14:57:01] [ERROR] red: Exception in command 'taxon'
Traceback (most recent call last):
  File "/home/redbot/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/redbot/.local/share/Dronefly/cogs/CogManager/cogs/inatcog/commands/taxon.py", line 54, in taxon
    await self.send_embed_for_taxon(ctx, query_response)
  File "/home/redbot/.local/share/Dronefly/cogs/CogManager/cogs/inatcog/embeds/inat.py", line 1365, in send_embed_for_taxon
    embed=await self.make_taxa_embed(
  File "/home/redbot/.local/share/Dronefly/cogs/CogManager/cogs/inatcog/embeds/inat.py", line 1051, in make_taxa_embed
    full_record = (
TypeError: 'NoneType' object is not subscriptable

It's not clear why response["results"] is None. For no matches, the API should return this instead:

{
  "total_results": 0,
  "page": 1,
  "per_page": 30,
  "results": []
}

Since the command that was typed was ,t sharks from italy and that ought to have matched the taxon, this sort of failure should probably be handled as a retriable condition in api.py. Unfortunately, we don't know what the record actually looked like. However, we ought to be able to sanity-check the result, such as:

Finally, carefully check that commands like make_taxa_embed already have exception handling for the final exception raised if the underlying API call runs out of retries and raises a final LookupError (just as we recently did for search / show observation).