Centralizing error handling to a helpers package

This commit is contained in:
Muyao CHEN 2024-07-03 10:03:25 +02:00
parent 0c0159734e
commit 9fc6c05d38
7 changed files with 65 additions and 20 deletions

View File

@ -5,10 +5,12 @@ import (
"fmt" "fmt"
"go-udemy-web-1/internal/config" "go-udemy-web-1/internal/config"
"go-udemy-web-1/internal/handlers" "go-udemy-web-1/internal/handlers"
"go-udemy-web-1/internal/helpers"
"go-udemy-web-1/internal/models" "go-udemy-web-1/internal/models"
"go-udemy-web-1/internal/render" "go-udemy-web-1/internal/render"
"log" "log"
"net/http" "net/http"
"os"
"time" "time"
"github.com/alexedwards/scs/v2" "github.com/alexedwards/scs/v2"
@ -17,8 +19,10 @@ import (
const portNumber = ":8080" const portNumber = ":8080"
var ( var (
app config.AppConfig app config.AppConfig
session *scs.SessionManager session *scs.SessionManager
infoLog *log.Logger
errorLog *log.Logger
) )
// main is the main application function // main is the main application function
@ -61,8 +65,15 @@ func run() error {
app.TemplateCahce = tc app.TemplateCahce = tc
app.UseCache = false app.UseCache = false
infoLog = log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime)
app.InfoLog = infoLog
errorLog = log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
app.ErrorLog = errorLog
repo := handlers.NewRepo(&app) repo := handlers.NewRepo(&app)
handlers.NewHandlers(repo) handlers.NewHandlers(repo)
helpers.NewHelpers(&app)
render.NewTemplates(&app) render.NewTemplates(&app)
return nil return nil

View File

@ -2,6 +2,7 @@ package config
import ( import (
"html/template" "html/template"
"log"
"github.com/alexedwards/scs/v2" "github.com/alexedwards/scs/v2"
) )
@ -11,5 +12,7 @@ type AppConfig struct {
TemplateCahce map[string]*template.Template TemplateCahce map[string]*template.Template
UseCache bool UseCache bool
InProduction bool InProduction bool
InfoLog *log.Logger
ErrorLog *log.Logger
Session *scs.SessionManager Session *scs.SessionManager
} }

View File

@ -5,9 +5,9 @@ import (
"fmt" "fmt"
"go-udemy-web-1/internal/config" "go-udemy-web-1/internal/config"
"go-udemy-web-1/internal/forms" "go-udemy-web-1/internal/forms"
"go-udemy-web-1/internal/helpers"
"go-udemy-web-1/internal/models" "go-udemy-web-1/internal/models"
"go-udemy-web-1/internal/render" "go-udemy-web-1/internal/render"
"log"
"net/http" "net/http"
) )
@ -33,23 +33,13 @@ func NewHandlers(r *Repository) {
// Home is the home page handler // Home is the home page handler
func (m *Repository) Home(w http.ResponseWriter, r *http.Request) { func (m *Repository) Home(w http.ResponseWriter, r *http.Request) {
remoteIP := r.RemoteAddr
m.App.Session.Put(r.Context(), "remote_ip", remoteIP)
render.RenderTemplate(w, r, "home.page.tmpl", &models.TemplateData{}) render.RenderTemplate(w, r, "home.page.tmpl", &models.TemplateData{})
} }
// About is the about page handler // About is the about page handler
func (m *Repository) About(w http.ResponseWriter, r *http.Request) { func (m *Repository) About(w http.ResponseWriter, r *http.Request) {
// perform some logic
stringMap := make(map[string]string)
stringMap["test"] = "Hello world!"
remoteIP := m.App.Session.GetString(r.Context(), "remote_ip")
stringMap["remote_ip"] = remoteIP
// send the data to the template // send the data to the template
render.RenderTemplate(w, r, "about.page.tmpl", &models.TemplateData{StringMap: stringMap}) render.RenderTemplate(w, r, "about.page.tmpl", &models.TemplateData{})
} }
// Contact is the contact page handler // Contact is the contact page handler
@ -86,7 +76,7 @@ func (m *Repository) MakeReservation(w http.ResponseWriter, r *http.Request) {
func (m *Repository) PostMakeReservation(w http.ResponseWriter, r *http.Request) { func (m *Repository) PostMakeReservation(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
log.Println(err) helpers.ServerError(w, err)
return return
} }
@ -123,7 +113,7 @@ func (m *Repository) PostMakeReservation(w http.ResponseWriter, r *http.Request)
func (m *Repository) ReservationSummary(w http.ResponseWriter, r *http.Request) { func (m *Repository) ReservationSummary(w http.ResponseWriter, r *http.Request) {
reservation, ok := m.App.Session.Get(r.Context(), "reservation").(models.Reservation) reservation, ok := m.App.Session.Get(r.Context(), "reservation").(models.Reservation)
if !ok { if !ok {
log.Println("connot get item from reservation") m.App.ErrorLog.Println("connot get item from session")
m.App.Session.Put(r.Context(), "error", "Can't get reservation from session") m.App.Session.Put(r.Context(), "error", "Can't get reservation from session")
http.Redirect(w, r, "/", http.StatusTemporaryRedirect) http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
} }
@ -164,7 +154,8 @@ func (m *Repository) AvailabilityJSON(w http.ResponseWriter, r *http.Request) {
out, err := json.MarshalIndent(resp, "", " ") out, err := json.MarshalIndent(resp, "", " ")
if err != nil { if err != nil {
log.Println(err) helpers.ServerError(w, err)
return
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View File

@ -9,6 +9,7 @@ import (
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"os"
"path/filepath" "path/filepath"
"time" "time"
@ -45,6 +46,12 @@ func getRoutes() http.Handler {
app.TemplateCahce = tc app.TemplateCahce = tc
app.UseCache = true // Not to use ./templates app.UseCache = true // Not to use ./templates
infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime)
app.InfoLog = infoLog
errorLog := log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
app.ErrorLog = errorLog
repo := NewRepo(&app) repo := NewRepo(&app)
NewHandlers(repo) NewHandlers(repo)

View File

@ -0,0 +1,26 @@
package helpers
import (
"fmt"
"go-udemy-web-1/internal/config"
"net/http"
"runtime/debug"
)
var app *config.AppConfig
// NewHelpers sets up app config for helpers
func NewHelpers(a *config.AppConfig) {
app = a
}
func ClientError(w http.ResponseWriter, status int) {
app.InfoLog.Println("Client error with status of", status)
http.Error(w, http.StatusText(status), status)
}
func ServerError(w http.ResponseWriter, err error) {
trace := fmt.Sprintf("%s\n%s", err.Error(), debug.Stack())
app.ErrorLog.Println(trace)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}

View File

@ -5,9 +5,9 @@ import (
"errors" "errors"
"fmt" "fmt"
"go-udemy-web-1/internal/config" "go-udemy-web-1/internal/config"
"go-udemy-web-1/internal/helpers"
"go-udemy-web-1/internal/models" "go-udemy-web-1/internal/models"
"html/template" "html/template"
"log"
"net/http" "net/http"
"path/filepath" "path/filepath"
@ -59,14 +59,14 @@ func RenderTemplate(w http.ResponseWriter, r *http.Request, tmpl string, td *mod
err := t.Execute(buf, td) err := t.Execute(buf, td)
if err != nil { if err != nil {
log.Println(err) helpers.ServerError(w, err)
return err return err
} }
// render the template // render the template
_, err = buf.WriteTo(w) _, err = buf.WriteTo(w)
if err != nil { if err != nil {
log.Println(err) helpers.ServerError(w, err)
return err return err
} }

View File

@ -4,6 +4,7 @@ import (
"encoding/gob" "encoding/gob"
"go-udemy-web-1/internal/config" "go-udemy-web-1/internal/config"
"go-udemy-web-1/internal/models" "go-udemy-web-1/internal/models"
"log"
"net/http" "net/http"
"os" "os"
"testing" "testing"
@ -32,6 +33,12 @@ func TestMain(m *testing.M) {
testApp.Session = session testApp.Session = session
infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime)
testApp.InfoLog = infoLog
errorLog := log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
testApp.ErrorLog = errorLog
app = &testApp app = &testApp
os.Exit(m.Run()) os.Exit(m.Run())