gui: New rest endpoint to get errors when web UI is opened
Since #4340 pulls aren't happening every 10s anymore and may be delayed up to 1h. This means that no folder error event reaches the web UI for a long time, thus no failed items will show up for a long time. Now errors are populated when the web UI is opened. GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4650 LGTM: AudriusButkevicius
This commit is contained in:
committed by
Audrius Butkevicius
parent
89a021609b
commit
fecb21cdb1
@@ -64,6 +64,7 @@ type service interface {
|
||||
Serve()
|
||||
Stop()
|
||||
CheckHealth() error
|
||||
PullErrors() []FileError
|
||||
|
||||
getState() (folderState, time.Time, error)
|
||||
setState(state folderState)
|
||||
@@ -119,7 +120,7 @@ var (
|
||||
errDeviceUnknown = errors.New("unknown device")
|
||||
errDevicePaused = errors.New("device is paused")
|
||||
errDeviceIgnored = errors.New("device is ignored")
|
||||
errFolderPaused = errors.New("folder is paused")
|
||||
ErrFolderPaused = errors.New("folder is paused")
|
||||
errFolderNotRunning = errors.New("folder is not running")
|
||||
errFolderMissing = errors.New("no such folder")
|
||||
errNetworkNotAllowed = errors.New("network not allowed")
|
||||
@@ -2226,6 +2227,15 @@ func (m *Model) State(folder string) (string, time.Time, error) {
|
||||
return state.String(), changed, err
|
||||
}
|
||||
|
||||
func (m *Model) PullErrors(folder string) ([]FileError, error) {
|
||||
m.fmut.RLock()
|
||||
defer m.fmut.RUnlock()
|
||||
if err := m.checkFolderRunningLocked(folder); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.folderRunners[folder].PullErrors(), nil
|
||||
}
|
||||
|
||||
func (m *Model) Override(folder string) {
|
||||
m.fmut.RLock()
|
||||
fs, ok := m.folderFiles[folder]
|
||||
@@ -2657,7 +2667,7 @@ func (m *Model) checkFolderRunningLocked(folder string) error {
|
||||
if cfg, ok := m.cfg.Folder(folder); !ok {
|
||||
return errFolderMissing
|
||||
} else if cfg.Paused {
|
||||
return errFolderPaused
|
||||
return ErrFolderPaused
|
||||
}
|
||||
|
||||
return errFolderNotRunning
|
||||
|
||||
@@ -3229,7 +3229,7 @@ func TestPausedFolders(t *testing.T) {
|
||||
}
|
||||
w.Wait()
|
||||
|
||||
if err := m.ScanFolder("default"); err != errFolderPaused {
|
||||
if err := m.ScanFolder("default"); err != ErrFolderPaused {
|
||||
t.Errorf("Expected folder paused error, received: %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -66,3 +66,7 @@ func (f *sendOnlyFolder) Serve() {
|
||||
func (f *sendOnlyFolder) String() string {
|
||||
return fmt.Sprintf("sendOnlyFolder/%s@%p", f.folderID, f)
|
||||
}
|
||||
|
||||
func (f *sendOnlyFolder) PullErrors() []FileError {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ func (f *sendReceiveFolder) pull(prevIgnoreHash string) (curIgnoreHash string, s
|
||||
// we're not making it. Probably there are write
|
||||
// errors preventing us. Flag this with a warning and
|
||||
// wait a bit longer before retrying.
|
||||
if folderErrors := f.currentErrors(); len(folderErrors) > 0 {
|
||||
if folderErrors := f.PullErrors(); len(folderErrors) > 0 {
|
||||
events.Default.Log(events.FolderErrors, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"errors": folderErrors,
|
||||
@@ -1797,11 +1797,11 @@ func (f *sendReceiveFolder) clearErrors() {
|
||||
f.errorsMut.Unlock()
|
||||
}
|
||||
|
||||
func (f *sendReceiveFolder) currentErrors() []fileError {
|
||||
func (f *sendReceiveFolder) PullErrors() []FileError {
|
||||
f.errorsMut.Lock()
|
||||
errors := make([]fileError, 0, len(f.errors))
|
||||
errors := make([]FileError, 0, len(f.errors))
|
||||
for path, err := range f.errors {
|
||||
errors = append(errors, fileError{path, err})
|
||||
errors = append(errors, FileError{path, err})
|
||||
}
|
||||
sort.Sort(fileErrorList(errors))
|
||||
f.errorsMut.Unlock()
|
||||
@@ -1880,13 +1880,13 @@ func (f *sendReceiveFolder) deleteDir(dir string, ignores *ignore.Matcher, scanC
|
||||
return err
|
||||
}
|
||||
|
||||
// A []fileError is sent as part of an event and will be JSON serialized.
|
||||
type fileError struct {
|
||||
// A []FileError is sent as part of an event and will be JSON serialized.
|
||||
type FileError struct {
|
||||
Path string `json:"path"`
|
||||
Err string `json:"error"`
|
||||
}
|
||||
|
||||
type fileErrorList []fileError
|
||||
type fileErrorList []FileError
|
||||
|
||||
func (l fileErrorList) Len() int {
|
||||
return len(l)
|
||||
|
||||
Reference in New Issue
Block a user