Repository: Cog-Creators/Red-DiscordBot

Issue:
Mongo troubles...
# Other bugs

<!-- 
Did you find a bug with something other than a command? Fill out the following:
-->

#### What were you trying to do?

1) Start the bot with a grandfathered Mongo configured. (`redbot <instance>`)
2) Convert the Mongo bot to json. (`redbot-setup convert <instance> json`)

#### What were you expecting to happen?

1) A friendly error.
2) The bot to convert from mongo to json

#### What actually happened?

1) Absolutely nothing. The bot exited silently.
```sh
zephyrkul@:~$ redbot <instance>
zephyrkul@:~$
```
2) An error was thrown telling me to convert to JSON first... while converting.
```py
Traceback (most recent call last):
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/bin/redbot-setup", line 8, in <module>
    sys.exit(run_cli())
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/setup.py", line 429, in run_cli
    cli()  # pylint: disable=no-value-for-parameter  # click
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/setup.py", line 398, in convert
    new_storage_details = loop.run_until_complete(do_migration(current_backend, target))
  File "/home/zephyrkul/.pyenv/versions/3.8.1/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete
    return future.result()
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/setup.py", line 210, in do_migration
    await config.migrate(cur_driver_cls, new_driver_cls)
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/core/config.py", line 1460, in migrate
    core_conf = Config.get_core_conf()
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/core/config.py", line 708, in get_core_conf
    return cls.get_conf(
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/core/config.py", line 683, in get_conf
    driver = get_driver(cog_name, uuid)
  File "/home/zephyrkul/.pyenv/versions/red-V3-3.8.1/lib/python3.8/site-packages/redbot/core/drivers/__init__.py", line 113, in get_driver
    raise RuntimeError(
RuntimeError: Please convert to JSON first to continue using the bot.Mongo support was removed in 3.2.
```


#### How can we reproduce this issue?

1) Have a MongoV2 bot instance from 3.1.9 or earlier.
2) Attempt to start the bot.
3) Mystically divine the fact that you must convert to JSON.
4) Attempt to convert to JSON.



Discussion:

Resolving patch:
diff --git a/redbot/__main__.py b/redbot/__main__.py
--- a/redbot/__main__.py
+++ b/redbot/__main__.py
@@ -466,6 +466,10 @@ def main():
         log.info("Shutting down with exit code: %s", exc.code)
         if red is not None:
             loop.run_until_complete(shutdown_handler(red, None, exc.code))
+    except Exception as exc:  # Non standard case.
+        log.exception("Unexpected exception (%s): ", type(exc), exc_info=exc)
+        if red is not None:
+            loop.run_until_complete(shutdown_handler(red, None, ExitCodes.CRITICAL))
     finally:
         # Allows transports to close properly, and prevent new ones from being opened.
         # Transports may still not be closed correcly on windows, see below
diff --git a/redbot/core/config.py b/redbot/core/config.py
--- a/redbot/core/config.py
+++ b/redbot/core/config.py
@@ -643,7 +643,14 @@ def defaults(self):
         return pickle.loads(pickle.dumps(self._defaults, -1))
 
     @classmethod
-    def get_conf(cls, cog_instance, identifier: int, force_registration=False, cog_name=None):
+    def get_conf(
+        cls,
+        cog_instance,
+        identifier: int,
+        force_registration=False,
+        cog_name=None,
+        allow_old: bool = False,
+    ):
         """Get a Config instance for your cog.
 
         .. warning::
@@ -676,11 +683,16 @@ def get_conf(cls, cog_instance, identifier: int, force_registration=False, cog_n
             A new Config object.
 
         """
+        if allow_old:
+            log.warning(
+                "DANGER! This is getting an outdated driver. "
+                "Hopefully this is only being done from convert"
+            )
         uuid = str(identifier)
         if cog_name is None:
             cog_name = type(cog_instance).__name__
 
-        driver = get_driver(cog_name, uuid)
+        driver = get_driver(cog_name, uuid, allow_old=allow_old)
         if hasattr(driver, "migrate_identifier"):
             driver.migrate_identifier(identifier)
 
@@ -693,7 +705,7 @@ def get_conf(cls, cog_instance, identifier: int, force_registration=False, cog_n
         return conf
 
     @classmethod
-    def get_core_conf(cls, force_registration: bool = False):
+    def get_core_conf(cls, force_registration: bool = False, allow_old: bool = False):
         """Get a Config instance for the core bot.
 
         All core modules that require a config instance should use this
@@ -706,7 +718,11 @@ def get_core_conf(cls, force_registration: bool = False):
 
         """
         return cls.get_conf(
-            None, cog_name="Core", identifier=0, force_registration=force_registration
+            None,
+            cog_name="Core",
+            identifier=0,
+            force_registration=force_registration,
+            allow_old=allow_old,
         )
 
     def __getattr__(self, item: str) -> Union[Group, Value]:
@@ -1457,7 +1473,7 @@ def get_custom_lock(self, group_identifier: str) -> asyncio.Lock:
 async def migrate(cur_driver_cls: Type[BaseDriver], new_driver_cls: Type[BaseDriver]) -> None:
     """Migrate from one driver type to another."""
     # Get custom group data
-    core_conf = Config.get_core_conf()
+    core_conf = Config.get_core_conf(allow_old=True)
     core_conf.init_custom("CUSTOM_GROUPS", 2)
     all_custom_group_data = await core_conf.custom("CUSTOM_GROUPS").all()
 
diff --git a/redbot/core/drivers/__init__.py b/redbot/core/drivers/__init__.py
--- a/redbot/core/drivers/__init__.py
+++ b/redbot/core/drivers/__init__.py
@@ -73,7 +73,12 @@ def get_driver_class(storage_type: Optional[BackendType] = None) -> Type[BaseDri
 
 
 def get_driver(
-    cog_name: str, identifier: str, storage_type: Optional[BackendType] = None, **kwargs
+    cog_name: str,
+    identifier: str,
+    storage_type: Optional[BackendType] = None,
+    *,
+    allow_old: bool = False,
+    **kwargs,
 ):
     """Get a driver instance.
 
@@ -107,7 +112,10 @@ def get_driver(
             storage_type = BackendType.JSON
 
     try:
-        driver_cls: Type[BaseDriver] = get_driver_class(storage_type)
+        if not allow_old:
+            driver_cls: Type[BaseDriver] = get_driver_class(storage_type)
+        else:
+            driver_cls: Type[BaseDriver] = _get_driver_class_include_old(storage_type)
     except ValueError:
         if storage_type in (BackendType.MONGOV1, BackendType.MONGO):
             raise RuntimeError(


Test patch: