Repository: syncthing/syncthing (language: go)

Issue:
Missing include file endlessly spams log
I misconfigured an `.stignore` file to include a file that did not exist:

```
$ cat /syncthing/notes/.stignore
// .stignore
#include .stglobalignore
```

This leads to syncthing logging an error at a very high rate (at least dozens of times per second):

```
$ tail -n20 /syncthing/syncthing.log
[FHHUZ] 21:57:28 WARNING: Error on folder "notes" (pyt9c-kd72a): loading ignores: parse error: failed to load include file .stglobalignore: open /syncthing/notes/.stglobalignore: no such file or directory
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now error
[FHHUZ] 21:57:28 INFO: Cleared error on folder "notes" (pyt9c-kd72a)
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now idle
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now sync-waiting
[FHHUZ] 21:57:28 WARNING: Error on folder "notes" (pyt9c-kd72a): loading ignores: parse error: failed to load include file .stglobalignore: open /syncthing/notes/.stglobalignore: no such file or directory
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now error
[FHHUZ] 21:57:28 INFO: Cleared error on folder "notes" (pyt9c-kd72a)
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now idle
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now sync-waiting
[FHHUZ] 21:57:28 WARNING: Error on folder "notes" (pyt9c-kd72a): loading ignores: parse error: failed to load include file .stglobalignore: open /syncthing/notes/.stglobalignore: no such file or directory
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now error
[FHHUZ] 21:57:28 INFO: Cleared error on folder "notes" (pyt9c-kd72a)
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now idle
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now sync-waiting
[FHHUZ] 21:57:28 WARNING: Error on folder "notes" (pyt9c-kd72a): loading ignores: parse error: failed to load include file .stglobalignore: open /syncthing/notes/.stglobalignore: no such file or directory
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now error
[FHHUZ] 21:57:28 INFO: Cleared error on folder "notes" (pyt9c-kd72a)
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now idle
[FHHUZ] 21:57:28 VERBOSE: Folder "pyt9c-kd72a" is now sync-waiting
```

I rotate my log files monthly; this error caused last month's log to grow to 20 GB on disk (would have been much larger without ZFS compression). I also found that RAM usage increased significantly with the file missing (normal: 300 MB, with missing file: 10 GB).

Expected behaviour would be that syncthing uses a longer retry interval before attempting to reload the missing included file.

System information: FreeBSD 13.0-RELEASE-p7, syncthing 1.18.1.


Discussion / hints:
One thought is offering an `#includeif` where it reports it only once if it can't load it. .gitconfig has this [feature](https://git-scm.com/docs/git-config#_includes).

Alternatively, we could make `#include` much quieter, but add an `#include!` which constantly whines (or even fails) if the file is missing.


Fix patch:
diff --git a/lib/model/folder.go b/lib/model/folder.go
index 396476be44e..a9b15e0de50 100644
--- a/lib/model/folder.go
+++ b/lib/model/folder.go
@@ -382,7 +382,6 @@ func (f *folder) pull() (success bool, err error) {
 		l.Debugln("Skipping pull of", f.Description(), "due to folder error:", err)
 		return false, err
 	}
-	f.setError(nil)
 
 	// Send only folder doesn't do any io, it only checks for out-of-sync
 	// items that differ in metadata and updates those.
@@ -409,6 +408,7 @@ func (f *folder) pull() (success bool, err error) {
 		l.Debugln("Skipping pull of", f.Description(), "due to folder error:", err)
 		return false, err
 	}
+	f.setError(nil)
 
 	success, err = f.puller.pull()
 
@@ -431,10 +431,6 @@ func (f *folder) scanSubdirs(subDirs []string) error {
 
 	err := f.getHealthErrorAndLoadIgnores()
 	if err != nil {
-		// If there is a health error we set it as the folder error. We do not
-		// clear the folder error if there is no health error, as there might be
-		// an *other* folder error (failed to load ignores, for example). Hence
-		// we do not use the CheckHealth() convenience function here.
 		return err
 	}
 	f.setError(nil)


Test patch: