http: panic serving [::1]:58965: runtime error: invalid memory address or nil pointer dereference

huangapple go评论67阅读模式
英文:

http: panic serving [::1]:58965: runtime error: invalid memory address or nil pointer dereference

问题

Go初学者,尝试创建一个简单的应用程序来读取CSV文件。然而,我认为我对错误的处理不够好,导致当我访问路径时应用程序失败。

我的代码:

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

错误日志:

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/mux@v1.8.0/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

根据我在网上阅读的内容,似乎是错误处理不好导致的问题?想知道如何修复这个问题以及我做错了什么。

英文:

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/mux@v1.8.0/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.

答案1

得分: 1

你的代码中有更多的错误:

如果 err == nil,你会返回 HTTP 500,但没有返回语句,所以代码会继续执行。如果发生任何错误,应该立即返回。

if err != nil {
    w.WriteHeader(http.StatusInternalServerError)
    return
}

在你的结构体中,你必须以大写字母开头命名字段。在 Go 中,通过将字段的首字母大写来导出(公开)字段。

type Client struct {
    Origin      string `csv:"origin"`
    Destination string `csv:"destination"`
    ...
}
英文:

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"`
    ...
}

huangapple
  • 本文由 发表于 2022年7月11日 02:16:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/72930818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定