From f4d4dc91b1125a417f7f1e2f704fe2925809ba1c Mon Sep 17 00:00:00 2001
From: Wim <wim@42.be>
Date: Sun, 25 Nov 2018 10:35:35 +0100
Subject: [PATCH] Add option to ignore failing bridge on start. Fixes #455
 (#603)

---
 bridge/config/config.go  |  1 +
 gateway/router.go        | 33 +++++++++++++++++++++++++++++++--
 matterbridge.toml.sample |  6 ++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/bridge/config/config.go b/bridge/config/config.go
index 064f04a4..48c36d9d 100644
--- a/bridge/config/config.go
+++ b/bridge/config/config.go
@@ -72,6 +72,7 @@ type Protocol struct {
 	EditSuffix             string // mattermost, slack, discord, telegram, gitter
 	EditDisable            bool   // mattermost, slack, discord, telegram, gitter
 	IconURL                string // mattermost, slack
+	IgnoreFailureOnStart   bool   // general
 	IgnoreNicks            string // all protocols
 	IgnoreMessages         string // all protocols
 	Jid                    string // xmpp
diff --git a/gateway/router.go b/gateway/router.go
index 99b34378..13e8ddd8 100644
--- a/gateway/router.go
+++ b/gateway/router.go
@@ -54,17 +54,46 @@ func (r *Router) Start() error {
 		flog.Infof("Starting bridge: %s ", br.Account)
 		err := br.Connect()
 		if err != nil {
-			return fmt.Errorf("Bridge %s failed to start: %v", br.Account, err)
+			e := fmt.Errorf("Bridge %s failed to start: %v", br.Account, err)
+			if r.disableBridge(br, e) {
+				continue
+			}
+			return e
 		}
 		err = br.JoinChannels()
 		if err != nil {
-			return fmt.Errorf("Bridge %s failed to join channel: %v", br.Account, err)
+			e := fmt.Errorf("Bridge %s failed to join channel: %v", br.Account, err)
+			if r.disableBridge(br, e) {
+				continue
+			}
+			return e
+		}
+	}
+	// remove unused bridges
+	for _, gw := range r.Gateways {
+		for i, br := range gw.Bridges {
+			if br.Bridger == nil {
+				flog.Errorf("removing failed bridge %s", i)
+				delete(gw.Bridges, i)
+			}
 		}
 	}
 	go r.handleReceive()
 	return nil
 }
 
+// disableBridge returns true and empties a bridge if we have IgnoreFailureOnStart configured
+// otherwise returns false
+func (r *Router) disableBridge(br *bridge.Bridge, err error) bool {
+	if r.BridgeValues().General.IgnoreFailureOnStart {
+		flog.Error(err)
+		// setting this bridge empty
+		*br = bridge.Bridge{}
+		return true
+	}
+	return false
+}
+
 func (r *Router) getBridge(account string) *bridge.Bridge {
 	for _, gw := range r.Gateways {
 		if br, ok := gw.Bridges[account]; ok {
diff --git a/matterbridge.toml.sample b/matterbridge.toml.sample
index a4179b02..3bad9f45 100644
--- a/matterbridge.toml.sample
+++ b/matterbridge.toml.sample
@@ -1303,6 +1303,12 @@ MediaDownloadSize=1000000
 #OPTIONAL (default empty)
 MediaDownloadBlacklist=[".html$",".htm$"]
 
+#IgnoreFailureOnStart allows you to ignore failing bridges on startup.
+#Matterbridge will disable the failed bridge and continue with the other ones.
+#Context: https://github.com/42wim/matterbridge/issues/455
+#OPTIONAL (default false)
+IgnoreFailureOnStart=false
+
 ###################################################################
 #Gateway configuration
 ###################################################################