From 91ca7bf1baf7ab077bdd63a7a3930c15af5be325 Mon Sep 17 00:00:00 2001
From: Runxi Yu <me@runxiyu.org>
Date: Thu, 13 Feb 2025 09:33:19 +0800
Subject: [PATCH] http_*.go: Use http.Error

---
 config.go                  |  6 +++---
 http_handle_group_index.go |  9 ++++-----
 http_handle_index.go       |  9 ++++-----
 http_handle_login.go       | 12 ++++++------
 http_handle_repo_commit.go | 12 ++++++------
 http_handle_repo_index.go  | 13 ++++++-------
 http_handle_repo_log.go    |  9 ++++-----
 http_handle_repo_raw.go    | 18 +++++++++---------
 http_handle_repo_tree.go   | 23 +++++++++++------------
 http_handle_users.go       |  3 +--
 http_server.go             |  2 +-

diff --git a/config.go b/config.go
index 2fdd8c8d4b915ae78114d2d641f9a4e34d59fdc3..dbe06dee30a67ff6da58c46652e219a7836c00b8 100644
--- a/config.go
+++ b/config.go
@@ -16,9 +16,9 @@ var err_unsupported_database_type = errors.New("Unsupported database type")
 
 var config struct {
 	HTTP struct {
-		Net  string `scfg:"net"`
-		Addr string `scfg:"addr"`
-		CookieExpiry int `scfg:"cookie_expiry"`
+		Net          string `scfg:"net"`
+		Addr         string `scfg:"addr"`
+		CookieExpiry int    `scfg:"cookie_expiry"`
 	} `scfg:"http"`
 	SSH struct {
 		Net  string `scfg:"net"`
diff --git a/http_handle_group_index.go b/http_handle_group_index.go
index 9c910de679c7a1ec1610aa253121355e1d315117..c034853a60b8cbd7b7312fb097dfe0bdbbbba886 100644
--- a/http_handle_group_index.go
+++ b/http_handle_group_index.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 )
 
@@ -11,7 +10,7 @@
 	var names []string
 	rows, err := database.Query(r.Context(), "SELECT r.name FROM repos r JOIN groups g ON r.group_id = g.id WHERE g.name = $1;", group_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting groups:", err.Error())
+		http.Error(w, "Error getting groups:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	defer rows.Close()
@@ -19,14 +18,14 @@
 	for rows.Next() {
 		var name string
 		if err := rows.Scan(&name); err != nil {
-			fmt.Fprintln(w, "Error scanning row:", err.Error())
+			http.Error(w, "Error scanning row:: "+err.Error(), http.StatusInternalServerError)
 			return
 		}
 		names = append(names, name)
 	}
 
 	if err := rows.Err(); err != nil {
-		fmt.Fprintln(w, "Error iterating over rows:", err.Error())
+		http.Error(w, "Error iterating over rows:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
@@ -34,7 +33,7 @@ 	params["repos"] = names
 
 	err = templates.ExecuteTemplate(w, "group_repos", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template:", err.Error())
+		http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_index.go b/http_handle_index.go
index bbb10d83670dbb1e1a5c6d2fcc5d1d1d857aa333..8066a03b151a07a7f7bae5523170e5cf8f9c14ba 100644
--- a/http_handle_index.go
+++ b/http_handle_index.go
@@ -1,14 +1,13 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 )
 
 func handle_index(w http.ResponseWriter, r *http.Request, params map[string]any) {
 	rows, err := database.Query(r.Context(), "SELECT name FROM groups")
 	if err != nil {
-		fmt.Fprintln(w, "Error querying groups: " + err.Error())
+		http.Error(w, "Error querying groups: : "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	defer rows.Close()
@@ -17,14 +16,14 @@ 	groups := []string{}
 	for rows.Next() {
 		var groupName string
 		if err := rows.Scan(&groupName); err != nil {
-			fmt.Fprintln(w, "Error scanning group name: " + err.Error())
+			http.Error(w, "Error scanning group name: : "+err.Error(), http.StatusInternalServerError)
 			return
 		}
 		groups = append(groups, groupName)
 	}
 
 	if err := rows.Err(); err != nil {
-		fmt.Fprintln(w, "Error iterating over rows: " + err.Error())
+		http.Error(w, "Error iterating over rows: : "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
@@ -32,7 +31,7 @@ 	params["groups"] = groups
 
 	err = templates.ExecuteTemplate(w, "index", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template: " + err.Error())
+		http.Error(w, "Error rendering template: : "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_login.go b/http_handle_login.go
index 6f9885991afeefcf3ddbfb6a898ccc3c4afb1c1b..70a8c8b70685b3fd36c32ad3e72c2690107fe6b6 100644
--- a/http_handle_login.go
+++ b/http_handle_login.go
@@ -16,7 +16,7 @@ func handle_login(w http.ResponseWriter, r *http.Request, params map[string]any) {
 	if r.Method != "POST" {
 		err := templates.ExecuteTemplate(w, "login", params)
 		if err != nil {
-			fmt.Fprintln(w, "Error rendering template:", err.Error())
+			http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		}
 		return
 	}
@@ -32,17 +32,17 @@ 		if errors.Is(err, pgx.ErrNoRows) {
 			params["login_error"] = "Unknown username"
 			err := templates.ExecuteTemplate(w, "login", params)
 			if err != nil {
-				fmt.Fprintln(w, "Error rendering template:", err.Error())
+				http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 			}
 			return
 		}
-		fmt.Fprintln(w, "Error querying user information:", err.Error())
+		http.Error(w, "Error querying user information:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
 	match, err := argon2id.ComparePasswordAndHash(password, password_hash)
 	if err != nil {
-		fmt.Fprintln(w, "Error comparing password and hash:", err.Error())
+		http.Error(w, "Error comparing password and hash:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
@@ -50,7 +50,7 @@ 	if !match {
 		params["login_error"] = "Invalid password"
 		err := templates.ExecuteTemplate(w, "login", params)
 		if err != nil {
-			fmt.Fprintln(w, "Error rendering template:", err.Error())
+			http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 			return
 		}
 		return
@@ -75,7 +75,7 @@ 	http.SetCookie(w, &cookie)
 
 	_, err = database.Exec(r.Context(), "INSERT INTO sessions (user_id, session_id) VALUES ($1, $2)", user_id, cookie_value)
 	if err != nil {
-		fmt.Fprintln(w, "Error inserting session:", err.Error())
+		http.Error(w, "Error inserting session:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
diff --git a/http_handle_repo_commit.go b/http_handle_repo_commit.go
index 7469448c58dda107c0ad754b85660ac2a6e99c48..fe65756390b8d1ec1991a0f935cd36c67f5baa76 100644
--- a/http_handle_repo_commit.go
+++ b/http_handle_repo_commit.go
@@ -21,7 +21,7 @@ func handle_repo_commit(w http.ResponseWriter, r *http.Request, params map[string]any) {
 	group_name, repo_name, commit_id_specified_string := params["group_name"].(string), params["repo_name"].(string), params["commit_id"].(string)
 	repo, description, err := open_git_repo(r.Context(), group_name, repo_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error opening repo:", err.Error())
+		http.Error(w, "Error opening repo:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["repo_description"] = description
@@ -29,13 +29,13 @@ 	commit_id_specified_string_without_suffix := strings.TrimSuffix(commit_id_specified_string, ".patch")
 	commit_id := plumbing.NewHash(commit_id_specified_string_without_suffix)
 	commit_object, err := repo.CommitObject(commit_id)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting commit object:", err.Error())
+		http.Error(w, "Error getting commit object:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	if commit_id_specified_string_without_suffix != commit_id_specified_string {
 		patch, err := format_patch_from_commit(commit_object)
 		if err != nil {
-			fmt.Fprintln(w, "Error formatting patch:", err.Error())
+			http.Error(w, "Error formatting patch:: "+err.Error(), http.StatusInternalServerError)
 			return
 		}
 		fmt.Fprintln(w, patch)
@@ -53,13 +53,13 @@ 	params["commit_id"] = commit_id_string
 
 	parent_commit_hash, patch, err := get_patch_from_commit(commit_object)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting patch from commit:", err.Error())
+		http.Error(w, "Error getting patch from commit:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["parent_commit_hash"] = parent_commit_hash.String()
 	params["patch"] = patch
 
-	// TODO: Remove unnecessary context                                          
+	// TODO: Remove unnecessary context
 	// TODO: Prepend "+"/"-"/" " instead of solely distinguishing based on color
 	usable_file_patches := make([]usable_file_patch, 0)
 	for _, file_patch := range patch.FilePatches() {
@@ -81,7 +81,7 @@ 	params["file_patches"] = usable_file_patches
 
 	err = templates.ExecuteTemplate(w, "repo_commit", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template:", err.Error())
+		http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_repo_index.go b/http_handle_repo_index.go
index b0106707592513afdf57815d2a74bedb88ec087d..8a6f7b88a27019581c4a62ff38b76879f451a7a7 100644
--- a/http_handle_repo_index.go
+++ b/http_handle_repo_index.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 	"net/url"
 )
@@ -10,31 +9,31 @@ func handle_repo_index(w http.ResponseWriter, r *http.Request, params map[string]any) {
 	group_name, repo_name := params["group_name"].(string), params["repo_name"].(string)
 	repo, description, err := open_git_repo(r.Context(), group_name, repo_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error opening repo:", err.Error())
+		http.Error(w, "Error opening repo:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["repo_description"] = description
 	head, err := repo.Head()
 	if err != nil {
-		fmt.Fprintln(w, "Error getting repo HEAD:", err.Error())
+		http.Error(w, "Error getting repo HEAD:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["ref"] = head.Name().Short()
 	head_hash := head.Hash()
 	recent_commits, err := get_recent_commits(repo, head_hash, 3)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting recent commits:", err.Error())
+		http.Error(w, "Error getting recent commits:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["commits"] = recent_commits
 	commit_object, err := repo.CommitObject(head_hash)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting commit object:", err.Error())
+		http.Error(w, "Error getting commit object:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	tree, err := commit_object.Tree()
 	if err != nil {
-		fmt.Fprintln(w, "Error getting file tree:", err.Error())
+		http.Error(w, "Error getting file tree:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
@@ -45,7 +44,7 @@ 	params["clone_url"] = "ssh://" + r.Host + "/" + url.PathEscape(group_name) + "/:/repos/" + url.PathEscape(repo_name)
 
 	err = templates.ExecuteTemplate(w, "repo_index", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template:", err.Error())
+		http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_repo_log.go b/http_handle_repo_log.go
index 0f79ecb31ea1e497658e101d4b87005729254139..bdc0d780c5907801953184afda6423e6f2ca8e55 100644
--- a/http_handle_repo_log.go
+++ b/http_handle_repo_log.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 
 	"github.com/go-git/go-git/v5/plumbing"
@@ -12,26 +11,26 @@ func handle_repo_log(w http.ResponseWriter, r *http.Request, params map[string]any) {
 	group_name, repo_name, ref_name := params["group_name"].(string), params["repo_name"].(string), params["ref"].(string)
 	repo, description, err := open_git_repo(r.Context(), group_name, repo_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error opening repo:", err.Error())
+		http.Error(w, "Error opening repo:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["repo_description"] = description
 	ref, err := repo.Reference(plumbing.NewBranchReferenceName(ref_name), true)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting repo reference:", err.Error())
+		http.Error(w, "Error getting repo reference:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	ref_hash := ref.Hash()
 	commits, err := get_recent_commits(repo, ref_hash, -1)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting recent commits:", err.Error())
+		http.Error(w, "Error getting recent commits:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["commits"] = commits
 
 	err = templates.ExecuteTemplate(w, "repo_log", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template:", err.Error())
+		http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_repo_raw.go b/http_handle_repo_raw.go
index 7d25071146d645aaa22c4adc4db10478ac83aa35..ba67ac1947fd11caf5dde8eb0f00e8c9dc559b48 100644
--- a/http_handle_repo_raw.go
+++ b/http_handle_repo_raw.go
@@ -1,8 +1,8 @@
 package main
 
 import (
-	"fmt"
 	"errors"
+	"fmt"
 	"net/http"
 	"path"
 	"strings"
@@ -19,7 +19,7 @@ 	if err != nil {
 		if errors.Is(err, err_no_ref_spec) {
 			ref_type = "head"
 		} else {
-			fmt.Fprintln(w, "Error querying ref type:", err.Error())
+			http.Error(w, "Error querying ref type:: "+err.Error(), http.StatusInternalServerError)
 			return
 		}
 	}
@@ -28,25 +28,25 @@ 	params["ref_type"], params["ref"], params["path_spec"] = ref_type, ref_name, path_spec
 
 	repo, description, err := open_git_repo(r.Context(), group_name, repo_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error opening repo:", err.Error())
+		http.Error(w, "Error opening repo:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["repo_description"] = description
 
 	ref_hash, err := get_ref_hash_from_type_and_name(repo, ref_type, ref_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting ref hash:", err.Error())
+		http.Error(w, "Error getting ref hash:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
 	commit_object, err := repo.CommitObject(ref_hash)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting commit object:", err.Error())
+		http.Error(w, "Error getting commit object:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	tree, err := commit_object.Tree()
 	if err != nil {
-		fmt.Fprintln(w, "Error getting file tree:", err.Error())
+		http.Error(w, "Error getting file tree:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
@@ -58,7 +58,7 @@ 		target, err = tree.Tree(path_spec)
 		if err != nil {
 			file, err := tree.File(path_spec)
 			if err != nil {
-				fmt.Fprintln(w, "Error retrieving path:", err.Error())
+				http.Error(w, "Error retrieving path:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			if len(raw_path_spec) != 0 && raw_path_spec[len(raw_path_spec)-1] == '/' {
@@ -67,7 +67,7 @@ 				return
 			}
 			file_contents, err := file.Contents()
 			if err != nil {
-				fmt.Fprintln(w, "Error reading file:", err.Error())
+				http.Error(w, "Error reading file:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			fmt.Fprintln(w, file_contents)
@@ -84,7 +84,7 @@ 	params["files"] = build_display_git_tree(target)
 
 	err = templates.ExecuteTemplate(w, "repo_raw_dir", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template:", err.Error())
+		http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_repo_tree.go b/http_handle_repo_tree.go
index b1a2d626d75ccb47452cf7083514d3cc4d976c69..cd88a6f541a04f7f2f1f49043f783ace5404b4dc 100644
--- a/http_handle_repo_tree.go
+++ b/http_handle_repo_tree.go
@@ -3,7 +3,6 @@
 import (
 	"bytes"
 	"errors"
-	"fmt"
 	"html/template"
 	"net/http"
 	"path"
@@ -23,31 +22,31 @@ 	if err != nil {
 		if errors.Is(err, err_no_ref_spec) {
 			ref_type = "head"
 		} else {
-			fmt.Fprintln(w, "Error querying ref type:", err.Error())
+			http.Error(w, "Error querying ref type:: "+err.Error(), http.StatusInternalServerError)
 			return
 		}
 	}
 	params["ref_type"], params["ref"], params["path_spec"] = ref_type, ref_name, path_spec
 	repo, description, err := open_git_repo(r.Context(), group_name, repo_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error opening repo:", err.Error())
+		http.Error(w, "Error opening repo:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	params["repo_description"] = description
 
 	ref_hash, err := get_ref_hash_from_type_and_name(repo, ref_type, ref_name)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting ref hash:", err.Error())
+		http.Error(w, "Error getting ref hash:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	commit_object, err := repo.CommitObject(ref_hash)
 	if err != nil {
-		fmt.Fprintln(w, "Error getting commit object:", err.Error())
+		http.Error(w, "Error getting commit object:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 	tree, err := commit_object.Tree()
 	if err != nil {
-		fmt.Fprintln(w, "Error getting file tree:", err.Error())
+		http.Error(w, "Error getting file tree:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 
@@ -59,7 +58,7 @@ 		target, err = tree.Tree(path_spec)
 		if err != nil {
 			file, err := tree.File(path_spec)
 			if err != nil {
-				fmt.Fprintln(w, "Error retrieving path:", err.Error())
+				http.Error(w, "Error retrieving path:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			if len(raw_path_spec) != 0 && raw_path_spec[len(raw_path_spec)-1] == '/' {
@@ -68,7 +67,7 @@ 				return
 			}
 			file_contents, err := file.Contents()
 			if err != nil {
-				fmt.Fprintln(w, "Error reading file:", err.Error())
+				http.Error(w, "Error reading file:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			lexer := chroma_lexers.Match(path_spec)
@@ -77,7 +76,7 @@ 				lexer = chroma_lexers.Fallback
 			}
 			iterator, err := lexer.Tokenise(nil, file_contents)
 			if err != nil {
-				fmt.Fprintln(w, "Error tokenizing code:", err.Error())
+				http.Error(w, "Error tokenizing code:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			var formatted_unencapsulated bytes.Buffer
@@ -85,7 +84,7 @@ 			style := chroma_styles.Get("autumn")
 			formatter := chroma_formatters_html.New(chroma_formatters_html.WithClasses(true), chroma_formatters_html.TabWidth(8))
 			err = formatter.Format(&formatted_unencapsulated, style, iterator)
 			if err != nil {
-				fmt.Fprintln(w, "Error formatting code:", err.Error())
+				http.Error(w, "Error formatting code:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			formatted_encapsulated := template.HTML(formatted_unencapsulated.Bytes())
@@ -93,7 +92,7 @@ 			params["file_contents"] = formatted_encapsulated
 
 			err = templates.ExecuteTemplate(w, "repo_tree_file", params)
 			if err != nil {
-				fmt.Fprintln(w, "Error rendering template:", err.Error())
+				http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 				return
 			}
 			return
@@ -110,7 +109,7 @@ 	params["files"] = build_display_git_tree(target)
 
 	err = templates.ExecuteTemplate(w, "repo_tree_dir", params)
 	if err != nil {
-		fmt.Fprintln(w, "Error rendering template:", err.Error())
+		http.Error(w, "Error rendering template:: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
diff --git a/http_handle_users.go b/http_handle_users.go
index 44133b0ed3f78ef348fb61283e3eb16011c25591..bf5939eb107a4f9a2216427a6cb9986f68a6cd57 100644
--- a/http_handle_users.go
+++ b/http_handle_users.go
@@ -1,10 +1,9 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 )
 
 func handle_users(w http.ResponseWriter, r *http.Request, params map[string]any) {
-	fmt.Fprintln(w, "Not implemented")
+	http.Error(w, "Not implemented", http.StatusNotImplemented)
 }
diff --git a/http_server.go b/http_server.go
index e769ace6bed1a6eb7603bcb433a6c58763918e57..917d68cef114fc7a0042ad47d9075b79d70708c6 100644
--- a/http_server.go
+++ b/http_server.go
@@ -4,8 +4,8 @@ import (
 	"errors"
 	"fmt"
 	"net/http"
-	"strings"
 	"strconv"
+	"strings"
 )
 
 type http_router_t struct{}

-- 
2.48.1