hugolib: Improve panic handling in layout rendering
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 14 Jul 2017 08:26:51 +0000 (10:26 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 14 Jul 2017 08:26:51 +0000 (10:26 +0200)
hugolib/site.go

index 6bbf9350c3d5752a51e489a5e1f651c9adb8909d..b663a39f02e43e54b285c405adc0a248992d3b17 100644 (file)
@@ -1966,27 +1966,40 @@ func (s *Site) renderAndWritePage(name string, dest string, p *PageOutput, layou
        return s.publish(dest, outBuffer)
 }
 
-func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts ...string) error {
+func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts ...string) (err error) {
+       var templ tpl.Template
+
        defer func() {
-               recover()
+               if r := recover(); r != nil {
+                       templName := ""
+                       if templ != nil {
+                               templName = templ.Name()
+                       }
+                       helpers.DistinctErrorLog.Printf("Failed to render %q: %s", templName, r)
+                       // TOD(bep) we really need to fix this. Also see below.
+                       if !s.running() && !testMode {
+                               os.Exit(-1)
+                       }
+               }
        }()
-       templ := s.findFirstTemplate(layouts...)
+
+       templ = s.findFirstTemplate(layouts...)
        if templ == nil {
                return fmt.Errorf("[%s] Unable to locate layout for %q: %s\n", s.Language.Lang, name, layouts)
        }
 
-       if err := templ.Execute(w, d); err != nil {
+       if err = templ.Execute(w, d); err != nil {
                // Behavior here should be dependent on if running in server or watch mode.
                helpers.DistinctErrorLog.Printf("Error while rendering %q: %s", name, err)
                if !s.running() && !testMode {
                        // TODO(bep) check if this can be propagated
                        os.Exit(-1)
                } else if testMode {
-                       return err
+                       return
                }
        }
 
-       return nil
+       return
 }
 
 func (s *Site) findFirstTemplate(layouts ...string) tpl.Template {