From 7d3b208e5c0f6a8b78b2eaaf552294e9a9ac44ac Mon Sep 17 00:00:00 2001 From: Ray Miller Date: Mon, 20 Apr 2020 12:43:41 +0100 Subject: [PATCH] Logging and better handling of RideWithGPS route not found. --- cmd/serve-rwgps/main.go | 33 ++++++++++++++------------------- pkg/rwgps/rwgps.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 19 deletions(-) create mode 100644 pkg/rwgps/rwgps.go diff --git a/cmd/serve-rwgps/main.go b/cmd/serve-rwgps/main.go index 9f5e7cd..6dbd7d7 100644 --- a/cmd/serve-rwgps/main.go +++ b/cmd/serve-rwgps/main.go @@ -3,14 +3,13 @@ package main import ( "bytes" "encoding/json" - "fmt" - "io/ioutil" "log" "net/http" "os" "strconv" "github.com/ray1729/gpx-utils/pkg/placenames" + "github.com/ray1729/gpx-utils/pkg/rwgps" ) func main() { @@ -32,27 +31,37 @@ var gpxSummarizer *placenames.GPXSummarizer func rwgpsHandler(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() x := q.Get("routeId") + log.Printf("Handilng request for routeId=%s", x) if x == "" { http.Error(w, "routeId is required", http.StatusBadRequest) return } routeId, err := strconv.Atoi(x) if err != nil { - http.Error(w, "invalid route id", http.StatusBadRequest) + log.Printf("Invalid route id: %s", x) + http.Error(w, "Invalid route id", http.StatusBadRequest) return } - track, err := FetchTrack(routeId) + track, err := rwgps.FetchTrack(routeId) if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + log.Println(err.Error()) + switch err.(type) { + case *rwgps.ErrNotFound: + http.Error(w, err.Error(), http.StatusNotFound) + default: + http.Error(w, err.Error(), http.StatusInternalServerError) + } return } summary, err := gpxSummarizer.SummarizeTrack(bytes.NewReader(track)) if err != nil { + log.Printf("Error analyzing route %d: %v", routeId, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } result, err := json.Marshal(summary) if err != nil { + log.Printf("Error marshalling JSON for route %d: %v", routeId, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -60,17 +69,3 @@ func rwgpsHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write(result) } - -func FetchTrack(routeId int) ([]byte, error) { - url := fmt.Sprintf("https://ridewithgps.com/routes/%d.gpx?sub_format=track", routeId) - resp, err := http.Get(url) - if err != nil { - return nil, fmt.Errorf("error getting %s: %v", url, err) - } - defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("error reading response from %s: %v", url, err) - } - return data, nil -} diff --git a/pkg/rwgps/rwgps.go b/pkg/rwgps/rwgps.go new file mode 100644 index 0000000..ba58374 --- /dev/null +++ b/pkg/rwgps/rwgps.go @@ -0,0 +1,37 @@ +package rwgps + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" +) + +type ErrNotFound struct { + RouteId int +} + +func (e *ErrNotFound) Error() string { + return fmt.Sprintf("RideWithGPS track %d not found", e.RouteId) +} + +func FetchTrack(routeId int) ([]byte, error) { + url := fmt.Sprintf("https://ridewithgps.com/routes/%d.gpx?sub_format=track", routeId) + resp, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("error getting %s: %v", url, err) + } + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("error reading response from %s: %v", url, err) + } + if IsNotFound(data) { + return nil, &ErrNotFound{routeId} + } + return data, nil +} + +func IsNotFound(data []byte) bool { + return bytes.HasPrefix(data, []byte("")) && bytes.Contains(data, []byte("Error (404 not found)")) +}