Browse Source

Correctly set and clear errors for missing folders (fixes #1937)

Audrius Butkevicius 10 years ago
parent
commit
1d856b4723

+ 1 - 1
gui/index.html

@@ -287,7 +287,7 @@
               <div class="panel-footer">
                 <button class="btn btn-sm btn-danger pull-left" ng-if="folderStatus(folder) == 'idle' && folder.readOnly && model[folder.id].needFiles > 0" ng-click="override(folder.id)" href=""><span class="glyphicon glyphicon-upload"></span>&nbsp;<span translate>Override Changes</span></button>
                 <span class="pull-right">
-                  <button class="btn btn-sm btn-default" href="" ng-show="folderStatus(folder) == 'idle'" ng-click="rescanFolder(folder.id)"><span class="glyphicon glyphicon-refresh"></span>&nbsp;<span translate>Rescan</span></button>
+                  <button class="btn btn-sm btn-default" href="" ng-show="['idle', 'stopped'].indexOf(folderStatus(folder)) > -1" ng-click="rescanFolder(folder.id)"><span class="glyphicon glyphicon-refresh"></span>&nbsp;<span translate>Rescan</span></button>
                   <button class="btn btn-sm btn-default" href="" ng-click="editFolder(folder)"><span class="glyphicon glyphicon-pencil"></span>&nbsp;<span translate>Edit</span></button>
                 </span>
                 <div class="clearfix"></div>

+ 1 - 0
gui/scripts/syncthing/core/controllers/syncthingController.js

@@ -140,6 +140,7 @@ angular.module('syncthing.core')
             var data = arg.data;
             if ($scope.model[data.folder]) {
                 $scope.model[data.folder].state = data.to;
+                $scope.model[data.folder].error = data.error;
             }
         });
 

File diff suppressed because it is too large
+ 1 - 1
internal/auto/gui.files.go


+ 23 - 1
internal/model/folderstate.go

@@ -71,7 +71,6 @@ func (s *stateTracker) setState(newState folderState) {
 		}
 
 		s.current = newState
-		s.err = nil
 		s.changed = time.Now()
 
 		events.Default.Log(events.StateChanged, eventData)
@@ -111,3 +110,26 @@ func (s *stateTracker) setError(err error) {
 	}
 	s.mut.Unlock()
 }
+
+// clearError sets the folder state to FolderIdle and clears the error
+func (s *stateTracker) clearError() {
+	s.mut.Lock()
+	if s.current == FolderError {
+		eventData := map[string]interface{}{
+			"folder": s.folder,
+			"to":     FolderIdle.String(),
+			"from":   s.current.String(),
+		}
+
+		if !s.changed.IsZero() {
+			eventData["duration"] = time.Since(s.changed).Seconds()
+		}
+
+		s.current = FolderIdle
+		s.err = nil
+		s.changed = time.Now()
+
+		events.Default.Log(events.StateChanged, eventData)
+	}
+	s.mut.Unlock()
+}

+ 8 - 1
internal/model/model.go

@@ -58,6 +58,7 @@ type service interface {
 
 	setState(state folderState)
 	setError(err error)
+	clearError()
 	getState() (folderState, time.Time, error)
 }
 
@@ -1287,6 +1288,12 @@ nextSub:
 
 	fchan, err := w.Walk()
 	if err != nil {
+		// The error we get here is likely an OS level error, which might not be
+		// as readable as our health check errors. Check if we can get a health
+		// check error first, and use that if it's available.
+		if ferr := m.CheckFolderHealth(folder); ferr != nil {
+			err = ferr
+		}
 		runner.setError(err)
 		return err
 	}
@@ -1714,7 +1721,7 @@ func (m *Model) CheckFolderHealth(id string) error {
 	} else if oldErr != nil {
 		l.Infof("Folder %q error is cleared, restarting", folder.ID)
 		if runnerExists {
-			runner.setState(FolderIdle)
+			runner.clearError()
 		}
 	}
 

Some files were not shown because too many files changed in this diff