Description

If you forget to import a template, you get a panic - shouldn't this be caught and a useful message printed to the console? (at least in debug mode)

How to reproduce

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func Index(c *gin.Context) {
    c.HTML(http.StatusOK, "index.tmpl", gin.H{
        "title": "Main website",
    })
}
func main() {
    route := gin.Default()
    //missing route.LoadHTMLFiles("index.tmpl")
    route.GET("/", Index)
    route.Run(":8802")
}

Expectations

[GIN-debug] [WARNING] template referenced but not found ...
[GIN] 2023/05/14 - 11:49:25 | 404 |         300ns |      10.0.0.145 | GET      "/"

Actual result

2023/05/14 11:49:47 [Recovery] 2023/05/14 - 11:49:47 panic recovered:
GET / HTTP/1.1
Host: debian:8802
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0


runtime error: invalid memory address or nil pointer dereference
/usr/local/go/src/runtime/panic.go:260 (0x44c51c)
        panicmem: panic(memoryError)
/usr/local/go/src/runtime/signal_unix.go:837 (0x44c4ec)
        sigpanic: panicmem()
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:937 (0x74b042)
        (*Context).HTML: instance := c.engine.HTMLRender.Instance(name, obj)
/home/voltagex/src/gin-bug-test/main.go:10 (0x7559db)
        Index: c.HTML(http.StatusOK, "index.tmpl", gin.H{
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:174 (0x74fd81)
        (*Context).Next: c.handlers[c.index](c)
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/recovery.go:102 (0x74fd6c)
        CustomRecoveryWithWriter.func1: c.Next()
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:174 (0x74eea6)
        (*Context).Next: c.handlers[c.index](c)
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/logger.go:240 (0x74ee89)
        LoggerWithConfig.func1: c.Next()
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:174 (0x74df2a)
        (*Context).Next: c.handlers[c.index](c)
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/gin.go:620 (0x74dbb1)
        (*Engine).handleHTTPRequest: c.Next()
/home/voltagex/go/pkg/mod/github.com/gin-gonic/gin@v1.9.0/gin.go:576 (0x74d85c)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2936 (0x6309f5)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1995 (0x62d311)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:1598 (0x468220)
        goexit: BYTE    $0x90   // NOP

Environment

  • go version: go version go1.20.4 linux/amd64
  • gin version (or commit ref): v1.9.0
  • operating system: Debian

Comment From: aliheydarabadii

Actually, gin is working exactly this way

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func Index(c *gin.Context) {
    c.HTML(http.StatusOK, "index.tmpl", gin.H{
        "title": "Main website",
    })
}
func main() {
    route := gin.Default()
    //missing route.LoadHTMLFiles("index.tmpl")
    route.LoadHTMLGlob("templates/*")
    route.GET("/", Index)
    route.Run(":8802")
}

you need just addroute.LoadHTMLGlob("templates/*") to get output like Error #01: html/template: "index.tmpl" is undefined

Comment From: voltagex

Sure, thanks @aliheydarabadii. My suggestion is that there's an error reminding you to load templates rather than a panic.