diff --git a/src/004-base/domPassage.js b/src/004-base/domPassage.js
index e051f45dd2766e3eea75262f6bf112a4f8117782..c5bc9037593c7ba8fc742b79c4f96208f4c952f9 100644
--- a/src/004-base/domPassage.js
+++ b/src/004-base/domPassage.js
@@ -25,21 +25,7 @@ App.DomPassage = class extends Passage {
 		try {
 			return this.callback();
 		} catch (ex) {
-			const fragment = document.createDocumentFragment();
-
-			App.UI.DOM.appendNewElement("p", fragment, `${ex.name}: ${ex.message}`, ["bold", "error"]);
-
-			const p = document.createElement("p");
-			const lines = ex.stack.split("\n");
-			for (const ll of lines) {
-				const div = document.createElement("div");
-				// remove file path from error message
-				div.append(ll.replace(/file:.*\//, "<path>/"));
-				p.append(div);
-			}
-			fragment.append(p);
-
-			return fragment;
+			return App.UI.DOM.formatException(ex);
 		}
 	}
 };
diff --git a/src/js/main.js b/src/js/main.js
index 750d32686277c38d6865c7cac47a8c4311cb13cf..a78c5e95b414dee619049a9d55072d5e989517bd 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -349,17 +349,7 @@ App.MainView.full = function() {
 
 		fragment.append(assemble());
 	} catch (ex) {
-		App.UI.DOM.appendNewElement("p", fragment, `${ex.name}: ${ex.message}`, ["bold", "error"]);
-
-		const p = document.createElement("p");
-		const lines = ex.stack.split("\n");
-		for (const ll of lines) {
-			const div = document.createElement("div");
-			// remove file path from error message
-			div.append(ll.replace(/file:.*\//, "<path>/"));
-			p.append(div);
-		}
-		fragment.append(p);
+		fragment.append(App.UI.DOM.formatException(ex));
 	}
 
 	return fragment;
diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js
index a904b1117d55ad28749c8419ac08551872fc53e8..926132a916b73f0c9d95ee497a8225994a06e769 100644
--- a/src/js/utilsDOM.js
+++ b/src/js/utilsDOM.js
@@ -438,3 +438,65 @@ App.UI.DOM.cashFormat = function(s) {
 	span.textContent = cashFormat(Math.trunc(s));
 	return span;
 };
+
+/**
+ * Renders an exception to DOM.
+ * Tries it's best to not fail itself.
+ *
+ * @param {Error } ex Exception
+ * @param {boolean} recursion set if formatException() called itself, never set from outside
+ * @returns {DocumentFragment|HTMLParagraphElement}
+ */
+App.UI.DOM.formatException = function formatException(ex, recursion = false) {
+	/**
+	 * In case the normal rendering failed attempts to provide some information on it.
+	 * In the worst case gives back a default error message.
+	 *
+	 * @param exception
+	 * @returns {DocumentFragment|HTMLParagraphElement}
+	 */
+	function failSafe(exception) {
+		if (!recursion) {
+			return formatException(exception, true);
+		} else {
+			// Not using custom functions here, as they may be the cause of the error
+			const p = document.createElement("p");
+			p.classList.add("bold", "error");
+			p.append("Unrecoverable error in App.UI.DOM.formatException()! Please report this.");
+			return p;
+		}
+	}
+
+	/**
+	 * Renders the exception to DOM
+	 *
+	 * @returns {DocumentFragment}
+	 */
+	function render() {
+		const fragment = document.createDocumentFragment();
+
+		App.UI.DOM.appendNewElement("p", fragment, `${ex.name}: ${ex.message}; ${Config.saves.version}`, ["bold", "error"]);
+
+		const p = document.createElement("p");
+		const lines = ex.stack.split("\n");
+		for (const ll of lines) {
+			const div = document.createElement("div");
+			// remove file path from error message
+			div.append(ll.replace(/file:.*\//, "<path>/"));
+			p.append(div);
+		}
+		fragment.append(p);
+
+		return fragment;
+	}
+
+	try {
+		if (!ex) {
+			// Create a new Error so we have access to a stacktrace.
+			return failSafe(new Error("No exception provided!"));
+		}
+		return render();
+	} catch (ex) {
+		return failSafe(ex);
+	}
+};