Repository: syncthing/syncthing (language: go)

Issue:
Make error message upon reaching the free space quota more clear
I just spent 10 minutes going back and forth because Syncthing kept spitting "out of disk space" errors, which is quite confusing when `df` says otherwise. 
Turns out I was just below the quota of 10% set for just that folder. 

I think, something like `Folder quota of X%/kB/MB/GB/TB free space reached` would be more appropriate than `insufficient disk space`, which sounds like the disk is just 100% full. 



Discussion / hints:
Doesn't the error actually say something like "insufficient disk space (5 MB < required 1%)"? (Not in front of a computer right now.)
@calmh 
> Puller (folder \*folder name\*, item "\*file name\*"): syncing: insufficient space in basic \*path\*

And sorry for the late reply, I clicked the GH notification, got distracted and just forgot

Fix patch:
diff --git a/lib/config/folderconfiguration.go b/lib/config/folderconfiguration.go
index 6f2e0ea6143..214343db696 100644
--- a/lib/config/folderconfiguration.go
+++ b/lib/config/folderconfiguration.go
@@ -261,8 +261,8 @@ func (f *FolderConfiguration) CheckAvailableSpace(req uint64) error {
 	if err != nil {
 		return nil
 	}
-	if !checkAvailableSpace(req, f.MinDiskFree, usage) {
-		return fmt.Errorf("insufficient space in %v %v", fs.Type(), fs.URI())
+	if err := checkAvailableSpace(req, f.MinDiskFree, usage); err != nil {
+		return fmt.Errorf("insufficient space in folder %v (%v): %w", f.Description(), fs.URI(), err)
 	}
 	return nil
 }
diff --git a/lib/config/size.go b/lib/config/size.go
index 8e92c82e6ab..1124d0e386c 100644
--- a/lib/config/size.go
+++ b/lib/config/size.go
@@ -83,10 +83,10 @@ func CheckFreeSpace(minFree Size, usage fs.Usage) error {
 	if minFree.Percentage() {
 		freePct := (float64(usage.Free) / float64(usage.Total)) * 100
 		if freePct < val {
-			return fmt.Errorf("%.1f %% < %v", freePct, minFree)
+			return fmt.Errorf("current %.2f %% < required %v", freePct, minFree)
 		}
 	} else if float64(usage.Free) < val {
-		return fmt.Errorf("%sB < %v", formatSI(usage.Free), minFree)
+		return fmt.Errorf("current %sB < required %v", formatSI(usage.Free), minFree)
 	}
 
 	return nil
@@ -94,12 +94,12 @@ func CheckFreeSpace(minFree Size, usage fs.Usage) error {
 
 // checkAvailableSpace checks that the free space does not fall below the minimum
 // required free space, considering additional required space for a future operation.
-func checkAvailableSpace(req uint64, minFree Size, usage fs.Usage) bool {
+func checkAvailableSpace(req uint64, minFree Size, usage fs.Usage) error {
 	if usage.Free < req {
-		return false
+		return fmt.Errorf("current %sB < required %sB", formatSI(usage.Free), formatSI(req))
 	}
 	usage.Free -= req
-	return CheckFreeSpace(minFree, usage) == nil
+	return CheckFreeSpace(minFree, usage)
 }
 
 func formatSI(b uint64) string {
diff --git a/lib/model/folder.go b/lib/model/folder.go
index 4b645ebd0c6..396476be44e 100644
--- a/lib/model/folder.go
+++ b/lib/model/folder.go
@@ -329,7 +329,7 @@ func (f *folder) getHealthErrorWithoutIgnores() error {
 	dbPath := locations.Get(locations.Database)
 	if usage, err := fs.NewFilesystem(fs.FilesystemTypeBasic, dbPath).Usage("."); err == nil {
 		if err = config.CheckFreeSpace(f.model.cfg.Options().MinHomeDiskFree, usage); err != nil {
-			return errors.Wrapf(err, "insufficient space on disk for database (%v)", dbPath)
+			return fmt.Errorf("insufficient space on disk for database (%v): %w", dbPath, err)
 		}
 	}
 


Test patch:
diff --git a/lib/config/size_test.go b/lib/config/size_test.go
index 2d094cd1c55..d47bdde34d7 100644
--- a/lib/config/size_test.go
+++ b/lib/config/size_test.go
@@ -159,8 +159,10 @@ func TestCheckAvailableSize(t *testing.T) {
 			continue
 		}
 		usage := fs.Usage{Free: tc.free, Total: tc.total}
-		if ok := checkAvailableSpace(tc.req, minFree, usage); ok != tc.ok {
-			t.Errorf("checkAvailableSpace(%v, %v, %v) == %v, expected %v", tc.req, minFree, usage, ok, tc.ok)
+		err = checkAvailableSpace(tc.req, minFree, usage)
+		t.Log(err)
+		if (err == nil) != tc.ok {
+			t.Errorf("checkAvailableSpace(%v, %v, %v) == %v, expected %v", tc.req, minFree, usage, err, tc.ok)
 		}
 	}
 }