refactor error handling

master
nate smith 2019-09-10 16:00:25 -05:00
parent b9b70a6ad9
commit 2d8b85926f
1 changed files with 49 additions and 25 deletions

74
main.go
View File

@ -73,11 +73,10 @@ func homesDir() string {
return hDir return hDir
} }
func news() []NewsEntry { func getNews() (entries []NewsEntry, err error) {
inMeta := true inMeta := true
inContent := false inContent := false
current := NewsEntry{} current := NewsEntry{}
entries := []NewsEntry{}
blankLineRe := regexp.MustCompile(`^ *\n$`) blankLineRe := regexp.MustCompile(`^ *\n$`)
newsPath := os.Getenv("NEWS_PATH") newsPath := os.Getenv("NEWS_PATH")
@ -87,7 +86,7 @@ func news() []NewsEntry {
newsFile, err := os.Open(newsPath) newsFile, err := os.Open(newsPath)
if err != nil { if err != nil {
log.Fatalf("Unable to read news file: %v", err) return entries, errors.New(fmt.Sprintf("unable to read news file: %s", err))
} }
defer newsFile.Close() defer newsFile.Close()
@ -119,7 +118,7 @@ func news() []NewsEntry {
current.Content += fmt.Sprintf("\n%v", strings.TrimSpace(newsLine)) current.Content += fmt.Sprintf("\n%v", strings.TrimSpace(newsLine))
} }
} }
return entries return entries, nil
} }
func indexPathFor(username string) (string, error) { func indexPathFor(username string) (string, error) {
@ -217,7 +216,7 @@ func detectDefaultPageFor(username string, defaultHTML []byte) bool {
return bytes.Equal(indexHTML, defaultHTML) return bytes.Equal(indexHTML, defaultHTML)
} }
func getDefaultHTML() []byte { func getDefaultHTML() ([]byte, error) {
indexPath := os.Getenv("DEFAULT_INDEX_PATH") indexPath := os.Getenv("DEFAULT_INDEX_PATH")
if indexPath == "" { if indexPath == "" {
indexPath = defaultIndexPath indexPath = defaultIndexPath
@ -225,30 +224,34 @@ func getDefaultHTML() []byte {
defaultIndexFile, err := os.Open(indexPath) defaultIndexFile, err := os.Open(indexPath)
if err != nil { if err != nil {
log.Fatal(err) return []byte{}, errors.New(fmt.Sprintf("could not open default index: %s", err))
} }
defer defaultIndexFile.Close() defer defaultIndexFile.Close()
defaultIndexHTML, err := ioutil.ReadAll(defaultIndexFile) defaultIndexHTML, err := ioutil.ReadAll(defaultIndexFile)
if err != nil { if err != nil {
log.Fatal(err) return []byte{}, errors.New(fmt.Sprintf("could not read default index: %s", err))
} }
return defaultIndexHTML return defaultIndexHTML, nil
} }
func getUsers() (users []User) { func getUsers() (users []User, err error) {
// TODO sort by mtime
// For the purposes of this program, we discover users via: // For the purposes of this program, we discover users via:
// - presence in /home/ // - presence in /home/
// - absence in systemUsers list (sourced from source code and potentially augmented by an environment variable) // - absence in systemUsers list (sourced from source code and potentially augmented by an environment variable)
// We formally used passwd parsing. This is definitely more "correct" and I'm // We formally used passwd parsing. This is definitely more "correct" and I'm
// not opposed to going back to that; going back to parsing /home is mainly to // not opposed to going back to that; going back to parsing /home is mainly to
// get this new version going. // get this new version going.
defaultIndexHTML := getDefaultHTML() defaultIndexHTML, err := getDefaultHTML()
if err != nil {
return users, err
}
out, err := exec.Command("ls", homesDir()).Output() out, err := exec.Command("ls", homesDir()).Output()
if err != nil { if err != nil {
log.Fatalf("could not run who %s", err) return users, errors.New(fmt.Sprintf("could not run ls: %s", err))
} }
scanner := bufio.NewScanner(bytes.NewReader(out)) scanner := bufio.NewScanner(bytes.NewReader(out))
@ -269,7 +272,7 @@ func getUsers() (users []User) {
users = append(users, user) users = append(users, user)
} }
return users return users, nil
} }
func liveUserCount(users []User) int { func liveUserCount(users []User) int {
@ -282,10 +285,10 @@ func liveUserCount(users []User) int {
return count return count
} }
func activeUserCount() int { func activeUserCount() (int, error) {
out, err := exec.Command("who").Output() out, err := exec.Command("who").Output()
if err != nil { if err != nil {
log.Fatalf("could not run who %s", err) return 0, errors.New(fmt.Sprintf("could not run who: %s", err))
} }
scanner := bufio.NewScanner(bytes.NewReader(out)) scanner := bufio.NewScanner(bytes.NewReader(out))
@ -298,19 +301,36 @@ func activeUserCount() int {
activeUsers[username] = true activeUsers[username] = true
} }
return len(activeUsers) return len(activeUsers), nil
} }
func uptime() string { func getUptime() (string, error) {
out, err := exec.Command("uptime").Output() out, err := exec.Command("uptime").Output()
if err != nil { if err != nil {
log.Fatalf("could not run uptime %s", err) return "", errors.New(fmt.Sprintf("could not run uptime: %s", err))
} }
return strings.TrimSpace(string(out)) return strings.TrimSpace(string(out)), nil
} }
func tdp() TildeData { func tdp() (TildeData, error) {
users := getUsers() users, err := getUsers()
if err != nil {
return TildeData{}, errors.New(fmt.Sprintf("could not get user list: %s", err))
}
activeUsers, err := activeUserCount()
if err != nil {
return TildeData{}, errors.New(fmt.Sprintf("could not count non-default users: %s", err))
}
news, err := getNews()
if err != nil {
return TildeData{}, errors.New(fmt.Sprintf("could not get news: %s", err))
}
uptime, err := getUptime()
if err != nil {
return TildeData{}, errors.New(fmt.Sprintf("could not determine uptime: %s", err))
}
return TildeData{ return TildeData{
Name: "tilde.town", Name: "tilde.town",
URL: "https://tilde.town", URL: "https://tilde.town",
@ -321,16 +341,20 @@ func tdp() TildeData {
UserCount: len(users), UserCount: len(users),
Users: users, Users: users,
LiveUserCount: liveUserCount(users), LiveUserCount: liveUserCount(users),
ActiveUserCount: activeUserCount(), ActiveUserCount: activeUsers,
Uptime: uptime(), Uptime: uptime,
News: news(), News: news,
GeneratedAt: time.Now().UTC().Format("2006-01-02 15:04:05"), GeneratedAt: time.Now().UTC().Format("2006-01-02 15:04:05"),
GeneratedAtSec: time.Now().Unix(), GeneratedAtSec: time.Now().Unix(),
} }, nil
} }
func main() { func main() {
data, err := json.Marshal(tdp()) systemData, err := tdp()
if err != nil {
log.Fatal(err)
}
data, err := json.Marshal(systemData)
if err != nil { if err != nil {
log.Fatalf("Failed to marshal JSON: %s", err) log.Fatalf("Failed to marshal JSON: %s", err)
} }