Skip to content

Commit

Permalink
improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcormier committed Aug 21, 2015
1 parent 1e692a2 commit 6e3efa7
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 33 deletions.
29 changes: 18 additions & 11 deletions args/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ var (
return value, err
}
if info.IsDir() {
return value, fmt.Errorf("invalid wallpaper; %s is a directory", value)
return value, fmt.Errorf("invalid wallpaper: %s is a directory", value)
}
return value, nil
},
Expand All @@ -132,28 +132,35 @@ var (
}
)

// Parse parses command line arguments and returns the preferences to apply or an error if there is any.
// Parses command line arguments and returns the preferences to apply or an error if there is any.
// If the help or version flag is passed, the corresponding message is printed and the program exits.
// If the arguments don't match one of the usage patterns, the usage message is printed and the program exits.
func Parse() (pref.Prefs, error) {
parsedArgs := defaultPrefs
opts, err := docopt.Parse(fmt.Sprintf(usage, programName), nil, true, fmt.Sprintf(version, programName), false)

opts, err := docopt.Parse(fmt.Sprintf(usage, programName), nil, true, fmt.Sprintf(version, programName), true)
if err != nil {
return parsedArgs, fmt.Errorf("cannot parse arguments (%s)", err)
}

for optKey, optValue := range opts {
if b, ok := optValue.(bool); !ok && optValue != nil || b {
if a, ok := argMap[optKey]; ok {
for key, value := range a.flagPrefs {
parsedArgs[key] = value
// this option has a value or is a flag and was specified
if argPref, ok := argMap[optKey]; ok {
// specifying this option has an effect that's not default so we process it
prefValue, err := argPref.value(optValue)
if err != nil {
return parsedArgs, err
}
for _, key := range a.valuePrefs {
value, err := a.value(optValue)
if err != nil {
return parsedArgs, err
}

for key, value := range argPref.flagPrefs {
parsedArgs[key] = value
}
for _, key := range argPref.valuePrefs {
parsedArgs[key] = prefValue
}
} else {

}
}
}
Expand Down
25 changes: 25 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"log"
)

func handleArgumentError(err error) int {
log.Printf("%s", err)
return 1
}

func handleDbReadError(err error) int {
log.Printf("error opening database (%s)", err)
return 2
}

func handleDbWriteError(err error) int {
log.Printf("error updating database (%s)", err)
return 3
}

func handleDbRollbackError(err error) int {
log.Printf("error aborting database changes (%s)", err)
return 4
}
54 changes: 32 additions & 22 deletions setwp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package main

import (
"database/sql"
"fmt"
"errors"
"log"
"os"
"os/exec"
"os/user"
"path/filepath"
Expand Down Expand Up @@ -37,79 +38,88 @@ const (
)

func main() {
// call another function to properly run defers
os.Exit(run())
}

func run() int {
log.SetFlags(0)

prefs, err := args.Parse()
if err != nil {
log.Fatalf("%s", err)
return handleArgumentError(err)
}

home, err := homeDir()
if err != nil {
log.Fatalf("cannot open database (%s)", err)
return handleDbReadError(err)
}
dbPath := filepath.Join(home, dbRelativePath)

db, err := sql.Open("sqlite3", dbPath)
if err != nil {
log.Fatalf("cannot open database (%s)", err)
return handleDbReadError(err)
}
defer db.Close()

tx, err := db.Begin()
if err != nil {
log.Fatalf("error updating database (%s)", err)
return handleDbWriteError(err)
}
success := false
defer closeTx(tx, &success)

clearDB(tx)
if err := clearDB(tx); err != nil {
return handleDbWriteError(err)
}
for key, value := range prefs {
setPref(tx, pref.Pref{Key: key, Value: value})
if err := setPref(tx, pref.Pref{Key: key, Value: value}); err != nil {
return handleDbWriteError(err)
}
}

success = true

if err := exec.Command("killall", "Dock").Run(); err != nil {
log.Println("error applying wallpaper, it will be applied on your next login")
}

return 0
}

// Clears the wallpaper preferences database.
func clearDB(tx *sql.Tx) {
if _, err := tx.Exec("delete from data; delete from preferences;"); err != nil {
log.Fatalf("error updating database (%s)", err)
}
func clearDB(tx *sql.Tx) error {
_, err := tx.Exec(clearDBStatement)
return err
}

// Sets a preference in the database.
func setPref(tx *sql.Tx, p pref.Pref) {
if _, err := tx.Exec(setPrefDBStatement, p.Value, p.Value, p.Key, p.Value); err != nil {
log.Fatalf("error updating database (%s)", err)
}
func setPref(tx *sql.Tx, p pref.Pref) error {
_, err := tx.Exec(setPrefDBStatement, p.Value, p.Value, p.Key, p.Value)
return err
}

// Commits or rollbacks the transaction depending on success.
func closeTx(tx *sql.Tx, success *bool) {
if *success {
if err := tx.Commit(); err != nil {
log.Fatalf("error updating database (%s)", err)
os.Exit(handleDbWriteError(err))
}
} else {
if err := tx.Rollback(); err != nil {
log.Fatalf("error aborting database changes (%s)", err)
os.Exit(handleDbRollbackError(err))
}
}
}

// Gets the current user's home directory.
func homeDir() (string, error) {
user, err := user.Current()
currentUser, err := user.Current()
if err != nil {
return "", fmt.Errorf("unknown current user")
return "", errors.New("unknown current user")
}
if user.HomeDir == "" {
return "", fmt.Errorf("unknown home directory")
if currentUser.HomeDir == "" {
return "", errors.New("unknown home directory")
}
return user.HomeDir, nil
return currentUser.HomeDir, nil
}

0 comments on commit 6e3efa7

Please sign in to comment.