Repository: Cog-Creators/Red-DiscordBot

Issue:
Removing an instance with nonexistant PostgreSQL database fails
### What Red version are you using?

3.4.13

### What were you trying to do?

Delete an instance with a nonexistent PostgreSQL database.

### What did you expect to happen?

The instance to be deleted.

### What actually happened?

A really long error message, and the instance did not get deleted.

### How can we reproduce this error?

1. Run redbot-setup <name>
2. Choose PostgreSQL
3. Input settings to a server that doesn't exist
4. Try to delete the instance


### Anything else?

[Discord support message where issue was found.](https://discord.com/channels/133049272517001216/387398816317440000/886422097692332052)
Removing an instance with nonexistant PostgreSQL database fails
### What Red version are you using?

3.4.13

### What were you trying to do?

Delete an instance with a nonexistent PostgreSQL database.

### What did you expect to happen?

The instance to be deleted.

### What actually happened?

A really long error message, and the instance did not get deleted.

### How can we reproduce this error?

1. Run redbot-setup <name>
2. Choose PostgreSQL
3. Input settings to a server that doesn't exist
4. Try to delete the instance


### Anything else?

[Discord support message where issue was found.](https://discord.com/channels/133049272517001216/387398816317440000/886422097692332052)


Discussion:
This is up for grabs, to fix this, the driver should only be initialized and teardown *if* the user actually asks to delete the db data. The relevant code can be seen here:
https://github.com/Cog-Creators/Red-DiscordBot/blob/eeed082542515350260b7f66f38cb5e8f74d1dd9/redbot/setup.py#L267-L283

It might also be worth showing a better error message on failure too, though we don't have uniform errors between different drivers which might be a bit of a problem here (catching *all* exceptions is a no go unless we do not hide the traceback). I would say that this is not necessary to address this issue and we can just deal with that in farther future.
is all that's needed here another `if delete_data is True:`?
This is up for grabs, to fix this, the driver should only be initialized and teardown *if* the user actually asks to delete the db data. The relevant code can be seen here:
https://github.com/Cog-Creators/Red-DiscordBot/blob/eeed082542515350260b7f66f38cb5e8f74d1dd9/redbot/setup.py#L267-L283

It might also be worth showing a better error message on failure too, though we don't have uniform errors between different drivers which might be a bit of a problem here (catching *all* exceptions is a no go unless we do not hide the traceback). I would say that this is not necessary to address this issue and we can just deal with that in farther future.
is all that's needed here another `if delete_data is True:`?

Resolving patch:
diff --git a/redbot/setup.py b/redbot/setup.py
--- a/redbot/setup.py
+++ b/redbot/setup.py
@@ -248,39 +248,41 @@ async def remove_instance(
     remove_datapath: Optional[bool] = None,
 ):
     data_manager.load_basic_configuration(instance)
+    backend = get_current_backend(instance)
 
     if interactive is True and delete_data is None:
-        delete_data = click.confirm(
-            "Would you like to delete this instance's data?", default=False
-        )
+        msg = "Would you like to delete this instance's data?"
+        if backend != BackendType.JSON:
+            msg += " The database server must be running for this to work."
+        delete_data = click.confirm(msg, default=False)
 
     if interactive is True and _create_backup is None:
-        _create_backup = click.confirm(
-            "Would you like to make a backup of the data for this instance?", default=False
-        )
+        msg = "Would you like to make a backup of the data for this instance?"
+        if backend != BackendType.JSON:
+            msg += " The database server must be running for this to work."
+        _create_backup = click.confirm(msg, default=False)
 
     if _create_backup is True:
         await create_backup(instance)
 
-    backend = get_current_backend(instance)
     driver_cls = drivers.get_driver_class(backend)
-    await driver_cls.initialize(**data_manager.storage_details())
-    try:
-        if delete_data is True:
+    if delete_data is True:
+        await driver_cls.initialize(**data_manager.storage_details())
+        try:
             await driver_cls.delete_all_data(interactive=interactive, drop_db=drop_db)
+        finally:
+            await driver_cls.teardown()
 
-        if interactive is True and remove_datapath is None:
-            remove_datapath = click.confirm(
-                "Would you like to delete the instance's entire datapath?", default=False
-            )
+    if interactive is True and remove_datapath is None:
+        remove_datapath = click.confirm(
+            "Would you like to delete the instance's entire datapath?", default=False
+        )
 
-        if remove_datapath is True:
-            data_path = data_manager.core_data_path().parent
-            safe_delete(data_path)
+    if remove_datapath is True:
+        data_path = data_manager.core_data_path().parent
+        safe_delete(data_path)
 
-        save_config(instance, {}, remove=True)
-    finally:
-        await driver_cls.teardown()
+    save_config(instance, {}, remove=True)
     print("The instance {} has been removed\n".format(instance))
 
 


Test patch: