Logging and better handling of RideWithGPS route not found.

This commit is contained in:
Ray Miller 2020-04-20 12:43:41 +01:00
parent a51a3634bd
commit 7d3b208e5c
2 changed files with 51 additions and 19 deletions

View file

@ -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
}

37
pkg/rwgps/rwgps.go Normal file
View file

@ -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("<!DOCTYPE html>")) && bytes.Contains(data, []byte("Error (404 not found)"))
}