diff --git a/snippetbox/cmd/web/handlers.go b/snippetbox/cmd/web/handlers.go index 57727e5..88de467 100644 --- a/snippetbox/cmd/web/handlers.go +++ b/snippetbox/cmd/web/handlers.go @@ -3,12 +3,11 @@ package main import ( "fmt" "html/template" - "log" "net/http" "strconv" ) -func home(w http.ResponseWriter, r *http.Request) { +func (app *application) home(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return @@ -20,29 +19,27 @@ func home(w http.ResponseWriter, r *http.Request) { } ts, err := template.ParseFiles(files...) if err != nil { - log.Print(err.Error()) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) + app.serverError(w, err) return } err = ts.ExecuteTemplate(w, "base", nil) if err != nil { - log.Print(err.Error()) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) + app.serverError(w, err) } } -func snippetView(w http.ResponseWriter, r *http.Request) { +func (app *application) snippetView(w http.ResponseWriter, r *http.Request) { id, err := strconv.Atoi(r.URL.Query().Get("id")) if err != nil || id < 1 { - http.NotFound(w, r) + app.notFound(w) return } fmt.Fprintf(w, "Display a specific snippet with ID %d...", id) } -func snippetCreate(w http.ResponseWriter, r *http.Request) { +func (app *application) snippetCreate(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { w.Header().Set("Allow", http.MethodPost) - http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) + app.clientError(w, http.StatusMethodNotAllowed) return } w.Write([]byte("Create a new snippet")) diff --git a/snippetbox/cmd/web/helpers.go b/snippetbox/cmd/web/helpers.go new file mode 100644 index 0000000..e1ecbfc --- /dev/null +++ b/snippetbox/cmd/web/helpers.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "net/http" + "runtime/debug" +) + +func (app *application) serverError(w http.ResponseWriter, err error) { + trace := fmt.Sprintf("%s\n%s", err.Error(), debug.Stack()) + app.errorLog.Output(2, trace) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) +} + +func (app *application) clientError(w http.ResponseWriter, status int) { + http.Error(w, http.StatusText(status), status) +} + +func (app *application) notFound(w http.ResponseWriter) { + app.clientError(w, http.StatusNotFound) +} diff --git a/snippetbox/cmd/web/main.go b/snippetbox/cmd/web/main.go index 6455f18..bfa4870 100644 --- a/snippetbox/cmd/web/main.go +++ b/snippetbox/cmd/web/main.go @@ -7,21 +7,25 @@ import ( "os" ) +type application struct { + errorLog *log.Logger + infoLog *log.Logger +} + func main() { addr := flag.String("addr", ":4000", "HTTP network address") flag.Parse() infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime) errorLog := log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile) - mux := http.NewServeMux() - fileServer := http.FileServer(http.Dir("./ui/static/")) - mux.Handle("/static/", http.StripPrefix("/static", fileServer)) - mux.HandleFunc("/", home) - mux.HandleFunc("/snippet/view", snippetView) - mux.HandleFunc("/snippet/create", snippetCreate) + app := &application{ + errorLog: errorLog, + infoLog: infoLog, + } + srv := &http.Server{ Addr: *addr, ErrorLog: errorLog, - Handler: mux, + Handler: app.routes(), } infoLog.Printf("Starting server on %s", *addr) err := srv.ListenAndServe() diff --git a/snippetbox/cmd/web/routes.go b/snippetbox/cmd/web/routes.go new file mode 100644 index 0000000..aa89d39 --- /dev/null +++ b/snippetbox/cmd/web/routes.go @@ -0,0 +1,13 @@ +package main + +import "net/http" + +func (app *application) routes() *http.ServerMux { + mux := http.NewServeMux() + fileServer := http.FileServer(http.Dir("./ui/static/")) + mux.Handle("/static", http.StripPrefix("/static", fileServer)) + mux.HandleFunc("/", app.home) + mux.HandleFunc("/snippet/view", app.snippetView) + mux.HandleFunc("/snippet/create", app.snippetCreate) + return mux +}