From 20a9758b89fa3ccdc34051cc96003ea49e6ff406 Mon Sep 17 00:00:00 2001 From: Michael Lynch Date: Mon, 15 Aug 2022 00:42:32 -0400 Subject: [PATCH] Add cleaner handling for when entry is not found (#158) * Add cleaner handling for when entry is not found * Fix unit tests --- handlers/paste.go | 9 +++++++-- handlers/paste_test.go | 4 ++-- store/sqlite/sqlite.go | 3 +++ store/store.go | 11 +++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/handlers/paste.go b/handlers/paste.go index 363e5ed..81245ca 100644 --- a/handlers/paste.go +++ b/handlers/paste.go @@ -14,6 +14,7 @@ import ( "github.com/gorilla/mux" "github.com/mtlynch/logpaste/random" + "github.com/mtlynch/logpaste/store" ) const MaxPasteCharacters = 2 * 1000 * 1000 @@ -28,8 +29,12 @@ func (s defaultServer) pasteGet() http.HandlerFunc { w.Header().Set("Content-Type", "text/plain; charset=UTF-8") contents, err := s.store.GetEntry(id) if err != nil { - log.Printf("Error retrieving entry with id %s: %v", id, err) - http.Error(w, "entry not found", http.StatusNotFound) + if _, ok := err.(store.EntryNotFoundError); ok { + http.Error(w, "entry not found", http.StatusNotFound) + return + } + log.Printf("failed to retrieve entry %s from datastore: %v", id, err) + http.Error(w, "failed to retrieve entry", http.StatusInternalServerError) return } io.WriteString(w, contents) diff --git a/handlers/paste_test.go b/handlers/paste_test.go index eed6bcb..c4761e7 100644 --- a/handlers/paste_test.go +++ b/handlers/paste_test.go @@ -2,7 +2,6 @@ package handlers import ( "encoding/json" - "errors" "fmt" "io/ioutil" "net/http" @@ -11,6 +10,7 @@ import ( "testing" "github.com/gorilla/mux" + "github.com/mtlynch/logpaste/store" ) type mockStore struct { @@ -21,7 +21,7 @@ func (ds mockStore) GetEntry(id string) (string, error) { if contents, ok := ds.entries[id]; ok { return contents, nil } - return "", errors.New("not found") + return "", store.EntryNotFoundError{ID: id} } func (ds *mockStore) InsertEntry(id string, contents string) error { diff --git a/store/sqlite/sqlite.go b/store/sqlite/sqlite.go index 9d5b19a..1216921 100644 --- a/store/sqlite/sqlite.go +++ b/store/sqlite/sqlite.go @@ -52,6 +52,9 @@ func New() store.Store { func (d db) GetEntry(id string) (string, error) { var contents string if err := d.ctx.QueryRow("SELECT contents FROM entries WHERE id=?", id).Scan(&contents); err != nil { + if err == sql.ErrNoRows { + return "", store.EntryNotFoundError{ID: id} + } return "", err } return contents, nil diff --git a/store/store.go b/store/store.go index 2731efe..8ca39cd 100644 --- a/store/store.go +++ b/store/store.go @@ -1,6 +1,17 @@ package store +import "fmt" + type Store interface { GetEntry(id string) (string, error) InsertEntry(id string, contents string) error } + +// EntryNotFoundError occurs when no entry exists with the given ID. +type EntryNotFoundError struct { + ID string +} + +func (f EntryNotFoundError) Error() string { + return fmt.Sprintf("could not find entry with ID=%v", f.ID) +}