Documentation
¶
Overview ¶
Package ehtml provides ways of rendering an error html page, using Go templates. It supports status code specific templates, with fallback to a generic error template. If no templates are defined, it uses a simple placeholder template.
Define some templates:
{{- define "head" -}}
<head>
<meta charset="utf-8">
<title>{{ .String }}</title>
</head>
{{- end -}}
{{- define "error" -}}
<!DOCTYPE html>
<html lang="en">
{{ template "head" . }}
<body>
<h1>{{ .Status.Int }} {{ .Status }}</h1>
<p>
{{ .Message }} while serving {{ .Request.URL.Path }}.
Request ID: {{ .ReqID }}
</p>
<p><i>This is a generic error page</i><p>
</body>
</html>
{{- end -}}
{{- define "500" -}}
<!DOCTYPE html>
<html lang="en">
{{ template "head" . }}
<body>
<h1>Snap!</h1>
<h2>{{ .Status.Int }} {{ .Status }}</h2>
<p>
Something went really wrong and we've been notified!
Please try again later.
</p>
<p><i>
Error: {{ .Message }} while serving {{ .Request.URL.Path }}.
Request ID: {{ .ReqID }}
</i></p>
</body>
</html>
{{- end -}}
{{- define "404" -}}
<!DOCTYPE html>
<html lang="en">
<head>
{{ template "head" . }}
</head>
<body>
<h1>{{ .Status.Int}} {{ .Status }}</h1>
<p>
{{ .Request.URL.Path }} could not be found.
</p>
</body>
</html>
{{- end -}}
Parse them into a globale variable (or part of your Handler object):
var errorPages = &Pages{template.Must(template.New("error").Parse(templates))}
If you are using Gorilla mux, set the `NotFoundHandler`
rtr := mux.NewRouter()
rtr.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := p.Render(w, &Data{Req: r, Code: http.StatusNotFound}); err != nil {
log.Println(err)
}
})
Optionally, extend `Data` to add more context. As an alternative, you can also roll your own implementation of `Provider`.
type data struct {
Data
ReqID int
}
And whenever something goes wrong in your handlers, call `Render()`:
err := p.Render(w, &data{Data{req, http.StatusInternalServerError, "DB connection"}, 666})
if err != nil {
log.Println(err)
}
Example ¶
p := &Pages{template.Must(template.New("error").Parse(exampleTemplates))}
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
w := httptest.NewRecorder()
// Extend Data, as needed
type data struct {
Data
ReqID int
}
// Serves the client with the "500" template
err := p.Render(w, &data{Data{req, http.StatusInternalServerError, "DB connection"}, 666})
if err != nil {
log.Println(err)
}
resp := w.Result()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(resp.StatusCode)
fmt.Println(string(body))
w = httptest.NewRecorder()
// 400 is not defined, so the generic "error" template is used instead.
err = p.Render(w, &data{Data{req, http.StatusBadRequest, "Missing token in URL"}, 667})
if err != nil {
log.Println(err)
}
resp = w.Result()
body, _ = ioutil.ReadAll(resp.Body)
fmt.Println(resp.StatusCode)
fmt.Println(string(body))
Example (NotFoundHandler) ¶
p := &Pages{template.Must(template.New("error").Parse(exampleTemplates))}
rtr := mux.NewRouter()
rtr.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := p.Render(w, &Data{Req: r, Code: http.StatusNotFound}); err != nil {
log.Println(err)
}
})
Index ¶
Examples ¶
Constants ¶
const DefaultTmpl = `` /* 224-byte string literal not displayed */
DefaultTmpl is a placeholder template for `Pages.Render()`
const RenderError = "500 Internal server error. While handling:\n%s"
RenderError is returned to the client if the template failed to render. This doesn't look nice, but it prevents partial responses.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Pages ¶
Pages allows setting of status page templates. Whenever such page needs to be served, a Lookup is done for a template named by the code. Eg: "404". A generic template named "error" can be provided and will be used if there is no status-specific template defined.
If Tmpl is `nil` or no templates are found using above Lookup scheme, `DefaultErrTmpl` will be used.
type Provider ¶ added in v0.2.0
type Provider interface {
// Request returns the incomming http Request object
Request() *http.Request
Status() Status
Message() string
// String returns the status code, status text and message in a single string.
// For example: "400 Bad Request: Parsing form data"
String() string
}
Provider of data to templates