Repository: frappe/frappe

Issue:
[Enhancement]Rollback operations if 'new-site' fails
If `bench new-site site-name` fails, if can leave behind an incomplete, unusable `Site`. 

I propose the this behavior be changed such that if a failure that will cause creation of a new `Site` is detected, frappe should remove every trace of the failed `Site`


Discussion:

Resolving patch:
diff --git a/frappe/commands/site.py b/frappe/commands/site.py
--- a/frappe/commands/site.py
+++ b/frappe/commands/site.py
@@ -67,6 +67,9 @@ def _new_site(db_name, site, mariadb_root_username=None, mariadb_root_password=N
 		scheduler_status = "disabled" if frappe.utils.scheduler.is_scheduler_disabled() else "enabled"
 		print "*** Scheduler is", scheduler_status, "***"
 
+	except frappe.exceptions.ImproperDBConfigurationError:
+		_drop_site(site, mariadb_root_username, mariadb_root_password, force=True)
+
 	finally:
 		if installing and os.path.exists(installing):
 			os.remove(installing)
@@ -326,6 +329,10 @@ def uninstall(context, app, dry_run=False, yes=False):
 @click.option('--archived-sites-path')
 @click.option('--force', help='Force drop-site even if an error is encountered', is_flag=True, default=False)
 def drop_site(site, root_login='root', root_password=None, archived_sites_path=None, force=False):
+	_drop_site(site, root_login, root_password, archived_sites_path, force)
+
+
+def _drop_site(site, root_login='root', root_password=None, archived_sites_path=None, force=False):
 	"Remove site from database and filesystem"
 	from frappe.installer import get_root_connection
 	from frappe.model.db_schema import DbManager
@@ -364,6 +371,7 @@ def drop_site(site, root_login='root', root_password=None, archived_sites_path=N
 
 	move(archived_sites_path, site)
 
+
 def move(dest_dir, site):
 	import os
 	if not os.path.isdir(dest_dir):
diff --git a/frappe/exceptions.py b/frappe/exceptions.py
--- a/frappe/exceptions.py
+++ b/frappe/exceptions.py
@@ -6,7 +6,8 @@
 # BEWARE don't put anything in this file except exceptions
 
 from werkzeug.exceptions import NotFound
-from MySQLdb import ProgrammingError as SQLError
+from MySQLdb import ProgrammingError as SQLError, Error
+
 
 class ValidationError(Exception):
 	http_status_code = 417
@@ -41,6 +42,19 @@ class Redirect(Exception):
 class CSRFTokenError(Exception):
 	http_status_code = 400
 
+
+class ImproperDBConfigurationError(Error):
+	"""
+	Used when frappe detects that database or tables are not properly
+	configured
+	"""
+	def __init__(self, reason, msg=None):
+		if not msg:
+			msg = "MariaDb is not properly configured"
+		super(ImproperDBConfigurationError, self).__init__(msg)
+		self.reason = reason
+
+
 class DuplicateEntryError(NameError):pass
 class DataError(ValidationError): pass
 class UnknownDomainError(Exception): pass
diff --git a/frappe/installer.py b/frappe/installer.py
--- a/frappe/installer.py
+++ b/frappe/installer.py
@@ -364,8 +364,9 @@ def check_if_ready_for_barracuda():
 			       "").format(x=site, sep2="\n"*2, sep="\n")
 
 			print_db_config(msg, expected_config_for_barracuda)
-			sys.exit(1)
-			# raise Exception, "MariaDB needs to be configured!"
+			raise frappe.exceptions.ImproperDBConfigurationError(
+				reason="MariaDB default file format is not Barracuda"
+			)
 
 
 def print_db_config(explanation, config_text):


Test patch: