package core
import (
"bytes"
"fmt"
"html/template"
"net/http"
)
// errorTmpl is compiled from a literal, not from the theme's template
// files -- a broken view template is exactly the situation this page has
// to survive, so it cannot depend on LoadTemplates succeeding.
var errorTmpl = template.Must(template.New("error").Parse(`
`))
// renderErrorPage never returns an error: if the template somehow fails to
// execute, it falls back to a plain-text body rather than propagating.
func renderErrorPage(code int, site string) (body []byte, contentType string) {
data := struct {
Code int
Status, Message, Site string
}{
Code: code,
Status: http.StatusText(code),
Message: friendlyMessage(code),
Site: site,
}
var buf bytes.Buffer
if err := errorTmpl.Execute(&buf, data); err != nil {
return []byte(fmt.Sprintf("%d %s\n", code, http.StatusText(code))), "text/plain; charset=utf-8"
}
return buf.Bytes(), "text/html; charset=utf-8"
}
// friendlyMessage keeps the diagnostic detail out of the response body --
// that stays in the server log -- while still telling a human what class
// of problem they hit.
func friendlyMessage(code int) string {
switch code {
case http.StatusNotFound:
return "We couldn't find that repository, ref, or path."
case http.StatusBadRequest:
return "That request doesn't look right."
case http.StatusRequestEntityTooLarge:
return "That response is too large to display in full."
default:
return "Something went wrong rendering this page. The details were logged."
}
}