Repository: Cog-Creators/Red-DiscordBot

Issue:
[ModLog] modlog.register_casetypes() fails silently
This one is a bit obscure, but I promise there is a good bug here. Lets say you have a cog which registers Case A, install that cog and have it running for an day. And you update the cog with a new case type, (Case B). The ``modlog.register_casetypes()`` will fail silently and refuse to add the new case type.

Here's some quick code to verify your self. (Make your own init), run this cog once, unload it, and add another case below the first case.

```py
import discord
from redbot.core import modlog, commands
import asyncio

BaseCog = getattr(commands, "Cog", object)

class TestModlog(BaseCog):

    def __init__(self, bot):
        self.bot = bot
        asyncio,ensure_future(self.register_cases())

    @staticmethod
    async def register_cases():
        cases = [
            {
                "name": "testcase1",
                "default_setting": True,
                "image": "\N{HAMMER}",
                "case_str": "Test case one.",
            }
        ]
```


Discussion:
Added in a temporary bypass in our cog while debugging the issue:
```
        # Temp workaround until register_casetypes fixed
        for c in cases:
            try:
                await modlog.register_casetype(c['name'], c['default_setting'], c['image'], c['case_str'], (c['audit_type'] if 'audit_type' in c else None))
                print(f"DEBUG {c['audit_type']}")
            except Exception as e:
                print(f"Case load {c['name']} failed - {e}")
                pass
```

Noticed another issue that may arise.  In modlog.py#L762 you're passing a dereferenced `new_type`.  This will fail in the above case, because audit_type is not explicitly defined, and resolves to "" instead of None.. and gets caught in the error handler @ https://github.com/Cog-Creators/Red-DiscordBot/blob/V3/develop/redbot/core/modlog.py#L698-L704
I don't think this is a bug. It fails "silently" only if you use `loop.create_task()` to register new cases. If you're registering cases during cog initialization you should do it with a call from `setup()` since any errors will propagate back to our error handler and be logged.

Regardless, this error is defined functionality in the documentation:
https://red-discordbot.readthedocs.io/en/v3-develop/framework_modlog.html#redbot.core.modlog.register_casetype

Resolving patch:
diff --git a/redbot/core/modlog.py b/redbot/core/modlog.py
--- a/redbot/core/modlog.py
+++ b/redbot/core/modlog.py
@@ -746,7 +746,6 @@ async def register_casetypes(new_types: List[dict]) -> List[CaseType]:
 
     Raises
     ------
-    RuntimeError
     KeyError
     ValueError
     AttributeError
@@ -761,13 +760,9 @@ async def register_casetypes(new_types: List[dict]) -> List[CaseType]:
         try:
             ct = await register_casetype(**new_type)
         except RuntimeError:
-            raise
-        except ValueError:
-            raise
-        except AttributeError:
-            raise
-        except TypeError:
-            raise
+            # We pass here because RuntimeError signifies the case was
+            # already registered.
+            pass
         else:
             type_list.append(ct)
     else:


Test patch: