2015-08-04 2 views
-1

Я пытаюсь добавить подтверждение для веб-приложения, основанного на базе GIN. На веб-странице я выбираю файл и отправляю, и сервер обрабатывает его. На стороне сервера я пытаюсь добавить проверку, чтобы проверить, указан ли файл или нет. Если нет, повторите перенаправление на исходную страницу.Проверка загрузки файлов в многопользовательском режиме в gin-gonic

func panic(err error) { 
     if err != nil { 
      log.Println(err) 
     } 
    } 

    func displayTable (c *gin.Context) {  
    file, _ , err := c.Request.FormFile("file") 
    panic(err) 
    if file == nil { 
     log.Println("File is nil.") 
     log.Println(err) 
     log.Println("*****") 
     c.HTML(http.StatusInternalServerError, "index.tmpl", gin.H{ 
      "title": "Select the input file","error" : "Please select the input file.", 
     })  
    } else { 
     defer file.Close() 
    } 
    filename := strconv.FormatInt(time.Now().Unix(),10) 
    out, err := os.Create("./tmp/"+filename+".xml") 
    panic(err) 
    defer out.Close() 
    _, err = io.Copy(out, file) 
    panic(err) 
    xmlFile, err := os.Open("./tmp/"+filename+".xml") 
    panic(err) 
    defer xmlFile.Close() 

    // Other Implementation Details 
} 

Даже после предоставления обработки я получаю панику в коде. Пожалуйста, дайте мне знать, что в реализации я пропущу.

Спасибо.

http: no such file 
    File is nil. 
    http: no such file 
    ***** 
    2015/08/04 13:19:10 Panic recovery -> runtime error: invalid memory address or nil pointer dereference 
    c:/go/src/runtime/panic.go:387 (0x414d36) 
    c:/go/src/runtime/panic.go:42 (0x4142a5) 
    c:/go/src/runtime/os_windows.go:42 (0x414066) 
    c:/go/src/io/io.go:362 (0x45268f) 
    D:/code/src/exmp/serverexmaple.go:45 (0x40168f) 
      displayTable: _, err = io.Copy(out, file) 
    D:/code/src/github.com/gin-gonic/gin/context.go:95 (0x49f8ea) 
      (*Context).Next: c.handlers[c.index](c) 
    D:/code/src/github.com/gin-gonic/gin/logger.go:56 (0x4ac490) 
      func.007: c.Next() 
    D:/code/src/github.com/gin-gonic/gin/context.go:95 (0x49f8ea) 
      (*Context).Next: c.handlers[c.index](c) 
    D:/code/src/github.com/gin-gonic/gin/recovery.go:43 (0x4acc80) 
      func.009: c.Next() 
    D:/code/src/github.com/gin-gonic/gin/context.go:95 (0x49f8ea) 
      (*Context).Next: c.handlers[c.index](c) 
    D:/code/src/github.com/gin-gonic/gin/gin.go:292 (0x4a46d5) 
      (*Engine).handleHTTPRequest: context.Next() 
    D:/code/src/github.com/gin-gonic/gin/gin.go:273 (0x4a4459) 
      (*Engine).ServeHTTP: engine.handleHTTPRequest(c) 
    c:/go/src/net/http/server.go:1703 (0x468415) 
    c:/go/src/net/http/server.go:1204 (0x466408) 
    c:/go/src/runtime/asm_386.s:2287 (0x438ea1) 
+2

Вы должны gofmt свой код и на самом деле включают в себя то, что у вас есть, это не может быть ваш реальный код: 'файл, _, эээ: = c.Request.FormFile («Файл»); panic (err) ' Во всяком случае, ошибка довольно ясна,' 2015/08/04 13:19:10 Паническое восстановление -> ошибка времени выполнения: неверный адрес памяти или разворот указателя нулевой точки, вы, скорее всего, пытаетесь разыменовать 'nil'. – user3591723

+0

@ user3591723 Если вы видите ошибку 'D: /code/src/exmp/serverexmaple.go: 45 (0x40168f) displayTable: _, err = io.Copy (out, file)', которая соответствует коду, является проблемной областью , Проблема в том, что когда значение файла равно нулю, оно не перенаправляется на страницу с ошибкой, а выполняет оставшуюся часть кода и, следовательно, получает панику при попытке прочитать значение nil. Является ли это распространенным поведением для джина? –

+1

Я не уверен, что такое общее поведение для джин, почему бы просто не вернуться с вашей функции? Кроме того, почему вы переопределяете 'panic'? .. Это встроенная функция, и для читаемости важно, чтобы это не было переопределено. – user3591723

ответ

0

Я понимаю, что я сделал ошибку с panic обработки. Проверка выполняется, если я добавляю оператор return после c.HTML. Это остановит функцию от выполнения остальной части кода. Благодаря @AlexAtNet за его совет, и я буду иметь в виду в будущем.

if file == nil { 
    log.Println("File is nil.") 
    log.Println(err) 
    log.Println("*****") 
    c.HTML(http.StatusInternalServerError, "index.tmpl", gin.H{ 
     "title": "Select the input file","error" : "Please select the input file.", 
    }) 
    return 
} 
2
  1. Пожалуйста, не переопределять panic. Это смущает всех, кто знает, как работает panic.
  2. Сравнение с nil немного сложнее в Go. Он может работать не так, как вы ожидаете: Check for nil and nil interface in Go. FormFile возвращает интерфейс, поэтому вам нужно отбросить его в базовую структуру, если вы хотите проверить его с помощью nil ИЛИ использовать второй параметр, тип которого доступен.
  3. Это не относится к GIN, она является частью реализации HTTP в Go содержит: http://golang.org/pkg/net/http/#Request.FormFile
+0

Спасибо за точку №1 и №2, которая будет иметь в виду в будущем. Но если я добавлю оператор 'return' после' c.HTML (http.StatusInternalServerError, "index.tmpl", gin.H {"title": «Выберите входной файл», «error»: «Пожалуйста, выберите входной файл . ",})' паника не отображается, и перенаправление, похоже, работает. –

+0

Ха, очевидно! В исходном коде вы проверяете, что файл равен нулю, и вызовите '_, err = io.Copy (out, file)', хотя он равен нулю. Конечно, вы должны добавить. –