Skip to content

Commit

Permalink
commands: Show server error info in browser
Browse files Browse the repository at this point in the history
The main item in this commit is showing of errors with a file context when running `hugo server`.

This can be turned off: `hugo server --disableBrowserError` (can also be set in `config.toml`).

But to get there, the error handling in Hugo needed a revision. There are some items left TODO for commits soon to follow, most notable errors in content and config files.

Fixes gohugoio#5284
Fixes gohugoio#5290
See gohugoio#5325
See gohugoio#5324
  • Loading branch information
bep committed Oct 16, 2018
1 parent 92979d9 commit 68d56bf
Show file tree
Hide file tree
Showing 73 changed files with 1,886 additions and 640 deletions.
61 changes: 58 additions & 3 deletions commands/commandeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,29 @@
package commands

import (
"bytes"
"errors"

"github.com/gohugoio/hugo/common/herrors"

"io/ioutil"

jww "github.com/spf13/jwalterweatherman"

"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"

"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/config"

"github.com/spf13/cobra"

"github.com/spf13/afero"

"github.com/gohugoio/hugo/hugolib"
"github.com/spf13/afero"

"github.com/bep/debounce"
"github.com/gohugoio/hugo/common/types"
Expand All @@ -46,6 +55,8 @@ type commandeerHugoState struct {
type commandeer struct {
*commandeerHugoState

logger *loggers.Logger

// Currently only set when in "fast render mode". But it seems to
// be fast enough that we could maybe just add it for all server modes.
changeDetector *fileChangeDetector
Expand All @@ -69,9 +80,45 @@ type commandeer struct {
serverPorts []int
languagesConfigured bool
languages langs.Languages
doLiveReload bool
fastRenderMode bool
showErrorInBrowser bool

configured bool
paused bool

// Any error from the last build.
buildErr error
}

func (c *commandeer) errCount() int {
return int(c.logger.ErrorCounter.Count())
}

func (c *commandeer) getErrorWithContext() interface{} {
errCount := c.errCount()

if errCount == 0 {
return nil
}

m := make(map[string]interface{})

m["Error"] = errors.New(removeErrorPrefixFromLog(c.logger.Errors.String()))
m["Version"] = hugoVersionString()

fe := herrors.UnwrapErrorWithFileContext(c.buildErr)
if fe != nil {
m["File"] = fe
}

if c.h.verbose {
var b bytes.Buffer
herrors.FprintStackTrace(&b, c.buildErr)
m["StackTrace"] = b.String()
}

return m
}

func (c *commandeer) Set(key string, value interface{}) {
Expand Down Expand Up @@ -105,6 +152,8 @@ func newCommandeer(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f fla
doWithCommandeer: doWithCommandeer,
visitedURLs: types.NewEvictingStringQueue(10),
debounce: rebuildDebouncer,
// This will be replaced later, but we need something to log to before the configuration is read.
logger: loggers.NewLogger(jww.LevelError, jww.LevelError, os.Stdout, ioutil.Discard, running),
}

return c, c.loadConfig(mustHaveConfigFile, running)
Expand Down Expand Up @@ -236,6 +285,11 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
c.languages = l
}

// Set some commonly used flags
c.doLiveReload = !c.h.buildWatch && !c.Cfg.GetBool("disableLiveReload")
c.fastRenderMode = c.doLiveReload && !c.Cfg.GetBool("disableFastRender")
c.showErrorInBrowser = c.doLiveReload && !c.Cfg.GetBool("disableBrowserError")

// This is potentially double work, but we need to do this one more time now
// that all the languages have been configured.
if c.doWithCommandeer != nil {
Expand All @@ -244,12 +298,13 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
}
}

logger, err := c.createLogger(config)
logger, err := c.createLogger(config, running)
if err != nil {
return err
}

cfg.Logger = logger
c.logger = logger

createMemFs := config.GetBool("renderToMemory")

Expand Down
28 changes: 2 additions & 26 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@
package commands

import (
"os"

"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"

"github.com/spf13/nitro"
)
Expand Down Expand Up @@ -242,7 +240,7 @@ func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
_ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
}

func checkErr(logger *jww.Notepad, err error, s ...string) {
func checkErr(logger *loggers.Logger, err error, s ...string) {
if err == nil {
return
}
Expand All @@ -255,25 +253,3 @@ func checkErr(logger *jww.Notepad, err error, s ...string) {
}
logger.ERROR.Println(err)
}

func stopOnErr(logger *jww.Notepad, err error, s ...string) {
if err == nil {
return
}

defer os.Exit(-1)

if len(s) == 0 {
newMessage := err.Error()
// Printing an empty string results in a error with
// no message, no bueno.
if newMessage != "" {
logger.CRITICAL.Println(newMessage)
}
}
for _, message := range s {
if message != "" {
logger.CRITICAL.Println(message)
}
}
}
4 changes: 2 additions & 2 deletions commands/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
package commands

import (
"fmt"
"time"

src "github.com/gohugoio/hugo/source"
"github.com/pkg/errors"

"github.com/gohugoio/hugo/hugolib"

Expand Down Expand Up @@ -187,7 +187,7 @@ func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, ma
}

if err = newPage.SaveSourceAs(newFilename); err != nil {
return fmt.Errorf("Failed to save file %q: %s", newFilename, err)
return errors.Wrapf(err, "Failed to save file %q:", newFilename)
}

return nil
Expand Down
Loading

0 comments on commit 68d56bf

Please sign in to comment.