maildir: Provide nicer error message on invalid url

If accounts.conf contains an invalid maildir url, return a nice
error instead of panicking.

Log a couple of different error cases to provide extra
information about the error to the user.
This commit is contained in:
Tero Koskinen 2020-07-25 11:11:13 +03:00 committed by Reto Brunner
parent c574a838fa
commit f81cc2803c
2 changed files with 34 additions and 4 deletions

View file

@ -21,15 +21,30 @@ type Container struct {
} }
// NewContainer creates a new container at the specified directory // NewContainer creates a new container at the specified directory
// TODO: return an error if the provided directory is not accessible func NewContainer(dir string, l *log.Logger) (*Container, error) {
func NewContainer(dir string, l *log.Logger) *Container { f, err := os.Open(dir)
return &Container{dir: dir, uids: uidstore.NewStore(), log: l} if err != nil {
return nil, err
}
defer f.Close()
s, err := f.Stat()
if err != nil {
return nil, err
}
if !s.IsDir() {
return nil, fmt.Errorf("Given maildir '%s' not a directory", dir)
}
return &Container{dir: dir, uids: uidstore.NewStore(), log: l}, nil
} }
// ListFolders returns a list of maildir folders in the container // ListFolders returns a list of maildir folders in the container
func (c *Container) ListFolders() ([]string, error) { func (c *Container) ListFolders() ([]string, error) {
folders := []string{} folders := []string{}
err := filepath.Walk(c.dir, func(path string, info os.FileInfo, err error) error { err := filepath.Walk(c.dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("Invalid path '%s': error: %v", path, err)
}
if !info.IsDir() { if !info.IsDir() {
return nil return nil
} }

View file

@ -1,6 +1,7 @@
package maildir package maildir
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"net/url" "net/url"
@ -221,7 +222,15 @@ func (w *Worker) handleConfigure(msg *types.Configure) error {
} }
dir = filepath.Join(home, u.Path) dir = filepath.Join(home, u.Path)
} }
w.c = NewContainer(dir, w.worker.Logger) if len(dir) == 0 {
return fmt.Errorf("could not resolve maildir from URL '%s'", msg.Config.Source)
}
c, err := NewContainer(dir, w.worker.Logger)
if err != nil {
w.worker.Logger.Printf("could not configure maildir: %s", dir)
return err
}
w.c = c
w.worker.Logger.Printf("configured base maildir: %s", dir) w.worker.Logger.Printf("configured base maildir: %s", dir)
return nil return nil
} }
@ -231,6 +240,12 @@ func (w *Worker) handleConnect(msg *types.Connect) error {
} }
func (w *Worker) handleListDirectories(msg *types.ListDirectories) error { func (w *Worker) handleListDirectories(msg *types.ListDirectories) error {
// TODO If handleConfigure has returned error, w.c is nil.
// It could be better if we skip directory listing completely
// when configure fails.
if w.c == nil {
return errors.New("Incorrect maildir directory")
}
dirs, err := w.c.ListFolders() dirs, err := w.c.ListFolders()
if err != nil { if err != nil {
w.worker.Logger.Printf("error listing directories: %v", err) w.worker.Logger.Printf("error listing directories: %v", err)