caddyfile: Better error message for missing site block braces (#4301)

Some new users mistakenly try to define two sites without braces around each. Doing this can yield a confusing error message saying that their site address is an "unknown directive".

We can do better by keeping track of whether the current site block was parsed with or without a brace, then changing the error message later based on that.

For example, now this invalid config:

```
foo.example.com
respond "foo"

bar.example.com
respond "bar"
```

Will yield this error message:

```
$ caddy adapt
2021/08/22 19:21:31.028 INFO    using adjacent Caddyfile
adapt: Caddyfile:4: unrecognized directive: bar.example.com
Did you mean to define a second site? If so, you must use curly braces around each site to separate their configurations.
```
This commit is contained in:
Francis Lavoie 2021-08-23 13:53:27 -04:00 committed by GitHub
parent d74913f871
commit 51f125bd44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View File

@ -211,6 +211,12 @@ func (p *parser) addresses() error {
if expectingAnother { if expectingAnother {
return p.Errf("Expected another address but had '%s' - check for extra comma", tkn) return p.Errf("Expected another address but had '%s' - check for extra comma", tkn)
} }
// Mark this server block as being defined with braces.
// This is used to provide a better error message when
// the user may have tried to define two server blocks
// without having used braces, which are required in
// that case.
p.block.HasBraces = true
break break
} }
@ -571,8 +577,9 @@ func (p *parser) snippetTokens() ([]Token, error) {
// head of the server block with tokens, which are // head of the server block with tokens, which are
// grouped by segments. // grouped by segments.
type ServerBlock struct { type ServerBlock struct {
Keys []string HasBraces bool
Segments []Segment Keys []string
Segments []Segment
} }
// DispenseDirective returns a dispenser that contains // DispenseDirective returns a dispenser that contains

View File

@ -170,7 +170,11 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,
dirFunc, ok := registeredDirectives[dir] dirFunc, ok := registeredDirectives[dir]
if !ok { if !ok {
tkn := segment[0] tkn := segment[0]
return nil, warnings, fmt.Errorf("%s:%d: unrecognized directive: %s", tkn.File, tkn.Line, dir) message := "%s:%d: unrecognized directive: %s"
if !sb.block.HasBraces {
message += "\nDid you mean to define a second site? If so, you must use curly braces around each site to separate their configurations."
}
return nil, warnings, fmt.Errorf(message, tkn.File, tkn.Line, dir)
} }
h := Helper{ h := Helper{