简体   繁体   中英

Golang: panic: runtime error: invalid memory address or nil pointer dereference

When uploading a file to my go app, I encounter a panic.

 panic: runtime error: invalid memory address or nil pointer dereference
 /Users/bob/Projects/go/src/github.com/zenazn/goji/web/middleware/recoverer.go:24 (0xbaf5b)
    func.006: debug.PrintStack()
 /usr/local/go/src/pkg/runtime/panic.c:248 (0x1043d)
    panic: runtime·newstackcall(d->fn, (byte*)d->args, d->siz);
 /usr/local/go/src/pkg/runtime/panic.c:552 (0x10eed)
    panicstring: runtime·panic(err);
 /usr/local/go/src/pkg/runtime/os_darwin.c:454 (0xfb8e)
    sigpanic: runtime·panicstring("invalid memory address or nil pointer dereference");
 /usr/local/go/src/pkg/mime/multipart/multipart.go:223 (0xb6801)
    (*Reader).NextPart: if r.currentPart != nil {
 /Users/bob/Projects/go/src/github.com/app/controllers/company_sheet_controller.go:32 (0x2ee18)
    NewCompanySheet: part, err := mr.NextPart()
 /usr/local/go/src/pkg/net/http/server.go:1235 (0x44f00)
    HandlerFunc.ServeHTTP: f(w, r)
 /Users/bob/Projects/go/src/github.com/zenazn/goji/web/router.go:113 (0x6bc0a)

This method handles an upload from a multipart form, extracting the file contents and boundary data. The r.FormFile method on request is used to set file and header. And in order to pull the additional data from the post, I use r.MultipartReader . From the error description I see r is already declared as ParseMultipartForm when using r.FormFile . When executing the function with the different request methods individually, I receive no errors. r.FormFile and r.MultipartReader work fine isolated. Am I unable to mix the two request methods?

func Upload(r *http.Request) {
  file, header, err := r.FormFile("file")
  ErrorCheck(err)

  mr, err := r.MultipartReader()
  ErrorCheck(err)
  part, err := mr.NextPart()
  ErrorCheck(err)

  var b bytes.Buffer
  io.CopyN(&b, part, int64(1<<20))
  fmt.Println(b.String())
  defer file.Close()
}

You are calling FormFile() at the beginning of your function.

This calls ParseMultipartForm() (see Request.FormFile ) which populates the MultipartForm field of your http.Request .

Now the documentation for MultipartReader() states that you should use MultipartReader() instead of ParseMultipartForm() if you want to process the data as stream.

Looking at the source MultipartReader() returns an error if the MultipartForm field was already set.

So to answer your question: No, you can't use both functions for the same request.

Also your

defer file.Close()

should be right after you checked for an error from FormFile(), otherwise the file won't be closed before Garbage Collection, when your function panics.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM