Go beginner, trying to create a simple app that reads a CSV file. However I think my poor handling of errors is causing my app to fail when I hit the path.
My code:
package handlers
import (
"fmt"
"net/http"
"os"
"github.com/gocarina/gocsv"
)
type Client struct {
origin string `csv:"origin"`
destination string `csv:"destination"`
flight_num string `csv:"flight_num"`
origin_latitude float32 `csv:"origin_latitude"`
origin_longitude float32 `csv:"origin_longitude"`
destination_latitude float32 `csv:"destination_latitude"`
destination_longitude float32 `csv:"destination_longitude"`
}
func (s *Server) getWeather(w http.ResponseWriter, r *http.Request) {
in, err := os.Open("data.csv")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
defer in.Close()
clients := []*Client{}
if err = gocsv.UnmarshalFile(in, &clients); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
for _, client := range clients {
fmt.Println("Hello, ", client.origin)
}
}
Error log:
2022/07/10 12:57:57 == route: /weather
2022/07/10 12:57:57 == method: GET
2022/07/10 12:57:57 http: panic serving [::1]:51696: runtime error: invalid memory address or nil pointer dereference
goroutine 34 [running]:
net/http.(*conn).serve.func1()
C:/Program Files/Go/src/net/http/server.go:1801 0xb9
panic({0x1023780, 0x12b6b40})
C:/Program Files/Go/src/runtime/panic.go:1047 0x266
health-check/api/handlers.(*Server).getWeather(0xd6d3e7, {0x10d4230, 0xc0001a21c0}, 0xc000162000)
C:/Users/anjar/challenge/training-A830284/health-check/api/handlers/weather.go:93 0x135
health-check/api/middlewares.MiddlewaresJSON.func1({0x10d4230, 0xc0001a21c0}, 0xc0000a0200)
C:/Users/anjar/challenge/training-A830284/health-check/api/middlewares/middlewares.go:18 0x191
net/http.HandlerFunc.ServeHTTP(0xc0000a0100, {0x10d4230, 0xc0001a21c0}, 0x16bfa961548)
C:/Program Files/Go/src/net/http/server.go:2046 0x2f
github.com/gorilla/mux.(*Router).ServeHTTP(0xc000148000, {0x10d4230, 0xc0001a21c0}, 0xc00018c500)
C:/Users/anjar/go/pkg/mod/github.com/gorilla/[email protected]/mux.go:210 0x1cf
net/http.serverHandler.ServeHTTP({0xc0001824e0}, {0x10d4230, 0xc0001a21c0}, 0xc00018c500)
C:/Program Files/Go/src/net/http/server.go:2878 0x43b
net/http.(*conn).serve(0xc00049e000, {0x10d55a0, 0xc00010f110})
C:/Program Files/Go/src/net/http/server.go:1929 0xb08
created by net/http.(*Server).Serve
C:/Program Files/Go/src/net/http/server.go:3033 0x4e8
From what I read online it seems to be a poor handling of errors? Would like to know how I can fix this and what I'm doing wrong.
CodePudding user response:
There are more bugs in your code:
If the err == nil
you give HTTP 500, but do not return, so the code runs. Return if any error occurs.
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
In your struct, you have to start your fields with a Capital letter. In go
you can export (make public) fields by capitalize the first letter of its name.
type Client struct {
Origin string `csv:"origin"`
Destination string `csv:"destination"`
...
}