ronantakizawa/codereview-bench huggingface dataset:
Repository: caddyserver/caddy
File: modules/caddyhttp/proxyprotocol/listenerwrapper.go (Go)

Code before:
	// allow/require PROXY headers from.
	Allow []string `json:"allow,omitempty"`

	policies []goproxy.PolicyFunc
}

// Provision sets up the listener wrapper.
func (pp *ListenerWrapper) Provision(ctx caddy.Context) error {
	if len(pp.Allow) > 0 {
		allowlist, err := goproxy.LaxWhiteListPolicy(pp.Allow)
		if err != nil {
			return err
		}
		pp.policies = append(pp.policies, allowlist)
	}
	return nil
}

// WrapListener adds PROXY protocol support to the listener.
func (pp *ListenerWrapper) WrapListener(l net.Listener) net.Listener {
	pl := &goproxy.Listener{
		Listener:          l,
		ReadHeaderTimeout: time.Duration(pp.Timeout),
	}
	if len(pp.policies) > 0 {
		pl.Policy = pp.policies[0]
	}
	return pl
}


Review comment (suggestion):
Just use a field of type `PolicyFunc` and assign it here.

Code after:
	// Allow is an optional list of CIDR ranges to
	// allow/require PROXY headers from.
	Allow []string `json:"allow,omitempty"`
	allow []netip.Prefix

	// Denby is an optional list of CIDR ranges to
	// deny PROXY headers from.
	Deny []string `json:"deny,omitempty"`
	deny []netip.Prefix

	// Accepted values are: ignore, use, reject, require, skip
	// default: ignore
	// Policy definitions are here: https://pkg.go.dev/github.com/pires/go-proxyproto@v0.7.0#Policy
	FallbackPolicy Policy `json:"fallback_policy,omitempty"`

	policy goproxy.PolicyFunc
}

// Provision sets up the listener wrapper.
func (pp *ListenerWrapper) Provision(ctx caddy.Context) error {
	for _, cidr := range pp.Allow {
		ipnet, err := netip.ParsePrefix(cidr)
		if err != nil {
			return err
		}
		pp.allow = append(pp.allow, ipnet)
	}
	for _, cidr := range pp.Deny {
		ipnet, err := netip.ParsePrefix(cidr)
		if err != nil {
			return err
		}
		pp.deny = append(pp.deny, ipnet)
	}
	pp.policy = func(upstream net.Addr) (goproxy.Policy, error) {
		// trust unix sockets
		if network := upstream.Network(); caddy.IsUnixNetwork(network) {
			return goproxy.USE, nil
		}
		ret := pp.FallbackPolicy
		host, _, err := net.SplitHostPort(upstream.String())
		if err != nil {
			return goproxy.REJECT, err
		}

		ip, err := netip.ParseAddr(host)
		if err != nil {
			return goproxy.REJECT, err
		}
		for _, ipnet := range pp.deny {
			if ipnet.Contains(ip) {
Repository: caddyserver/caddy
File: modules/caddyhttp/proxyprotocol/listenerwrapper.go (Go)

Code before:
}

// Provision sets up the listener wrapper.
func (pp *ListenerWrapper) Provision(ctx caddy.Context) error {
	for _, cidr := range pp.Allow {
		_, ipnet, err := net.ParseCIDR(cidr)
		if err != nil {
			return err
		}
		pp.allow = append(pp.allow, ipnet)
	}
	for _, cidr := range pp.Deny {
		_, ipnet, err := net.ParseCIDR(cidr)
		if err != nil {
			return err
		}
		pp.deny = append(pp.deny, ipnet)
	}
	pp.policy = func(upstream net.Addr) (goproxy.Policy, error) {
		ret := pp.FallbackPolicy
		host, _, err := net.SplitHostPort(upstream.String())
		if err != nil {
			return goproxy.REJECT, err
		}
		ip := net.ParseIP(host)
		if ip == nil {
			return goproxy.REJECT, err
		}
		for _, ipnet := range pp.deny {
			if ipnet.Contains(ip) {
				return goproxy.REJECT, nil
			}
		}
		for _, ipnet := range pp.allow {
			if ipnet.Contains(ip) {
				ret = PolicyUSE
				break
			}
		}
		return policyToGoProxyPolicy[ret], nil
	}
	return nil
}

// WrapListener adds PROXY protocol support to the listener.
func (pp *ListenerWrapper) WrapListener(l net.Listener) net.Listener {
	pl := &goproxy.Listener{
		Listener:          l,
		ReadHeaderTimeout: time.Duration(pp.Timeout),
	}
	pl.Policy = pp.policy

Review comment (bug):
What if the connection is made from a unix socket? It will be '@'. gin-gonic has a similar [bug](https://github.com/gin-gonic/gin/issues/2718) caused by [2632](https://github.com/gin-gonic/gin/pull/2632/files#diff-552f47512a00afe5fc6850cc9ddc830a6daeca162750e50aab4ed549685e0253R761).

Code after:
	policy goproxy.PolicyFunc
}

// Provision sets up the listener wrapper.
func (pp *ListenerWrapper) Provision(ctx caddy.Context) error {
	for _, cidr := range pp.Allow {
		ipnet, err := netip.ParsePrefix(cidr)
		if err != nil {
			return err
		}
		pp.allow = append(pp.allow, ipnet)
	}
	for _, cidr := range pp.Deny {
		ipnet, err := netip.ParsePrefix(cidr)
		if err != nil {
			return err
		}
		pp.deny = append(pp.deny, ipnet)
	}
	pp.policy = func(upstream net.Addr) (goproxy.Policy, error) {
		// trust unix sockets
		if network := upstream.Network(); caddy.IsUnixNetwork(network) {
			return goproxy.USE, nil
		}
		ret := pp.FallbackPolicy
		host, _, err := net.SplitHostPort(upstream.String())
		if err != nil {
			return goproxy.REJECT, err
		}

		ip, err := netip.ParseAddr(host)
		if err != nil {
			return goproxy.REJECT, err
		}
		for _, ipnet := range pp.deny {
			if ipnet.Contains(ip) {
				return goproxy.REJECT, nil
			}
		}
		for _, ipnet := range pp.allow {
			if ipnet.Contains(ip) {
				ret = PolicyUSE
				break
			}
		}
		return policyToGoProxyPolicy[ret], nil
	}
	return nil
}

// WrapListener adds PROXY protocol support to the listener.
Repository: caddyserver/caddy
File: modules/caddyhttp/fileserver/caddyfile.go (Go)

Code before:
//	    root          <path>
//	    hide          <files...>
//	    index         <files...>
//	    browse        [<template_file>]
//	    precompressed <formats...>
//	    status        <status>
//	    disable_canonical_uris
//	}
func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
	var fsrv FileServer

	for h.Next() {
		args := h.RemainingArgs()
		switch len(args) {
		case 0:
		case 1:
			if args[0] != "browse" {
				return nil, h.ArgErr()
			}
			fsrv.Browse = new(Browse)
		case 2:
			if args[0] != "browse" || args[1] != "reveal_symlink" {
				return nil, h.ArgErr()
			}
			fsrv.Browse = new(Browse)
			fsrv.Browse.RevealSymLink = true
		default:
			return nil, h.ArgErr()
		}

		for h.NextBlock(0) {
			switch h.Val() {
			case "fs":
				if !h.NextArg() {
					return nil, h.ArgErr()
				}
				if fsrv.FileSystemRaw != nil {
					return nil, h.Err("file system module already specified")
				}
				name := h.Val()
				modID := "caddy.fs." + name
				unm, err := caddyfile.UnmarshalModule(h.Dispenser, modID)
				if err != nil {
					return nil, err
				}
				fsys, ok := unm.(fs.FS)
				if !ok {
					return nil, h.Errf("module %s (%T) is not a supported file system implementation (requires fs.FS)", modID, unm)
				}
				fsrv.FileSystemRaw = caddyconfig.JSONModuleObject(fsys, "backend", name, nil)


Review comment (suggestion):
I think this option shouldn't be allowed inline, that's awkward. Instead, it should be a subdirective (like `browse` already is, taking a template file as an argument). Look at line 109.

Code after:
		return fsrv, err
	}
	err = fsrv.FinalizeUnmarshalCaddyfile(h)
	if err != nil {
		return nil, err
	}
	return fsrv, err
}

// UnmarshalCaddyfile parses the file_server directive. It enables
// the static file server and configures it with this syntax:
//
//	file_server [<matcher>] [browse] {
//	    fs            <filesystem>
//	    root          <path>
//	    hide          <files...>
//	    index         <files...>
//	    browse        [<template_file>]
//	    precompressed <formats...>
//	    status        <status>
//	    disable_canonical_uris
//	}
//
// The FinalizeUnmarshalCaddyfile method should be called after this
// to finalize setup of hidden Caddyfiles.
func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
	d.Next() // consume directive name

	args := d.RemainingArgs()
	switch len(args) {
	case 0:
	case 1:
		if args[0] != "browse" {
			return d.ArgErr()
		}
		fsrv.Browse = new(Browse)
	default:
		return d.ArgErr()
	}

	for d.NextBlock(0) {
		switch d.Val() {
		case "fs":
			if !d.NextArg() {
				return d.ArgErr()
			}
			if fsrv.FileSystem != "" {
				return d.Err("file system already specified")
			}
			fsrv.FileSystem = d.Val()
Repository: caddyserver/caddy
File: modules/caddyhttp/fileserver/caddyfile.go (Go)

Code before:
				if !h.Args(&fsrv.Root) {
					return nil, h.ArgErr()
				}

			case "browse":
				if fsrv.Browse != nil {
					return nil, h.Err("browsing is already configured")
				}
				fsrv.Browse = new(Browse)
				h.Args(&fsrv.Browse.TemplateFile)

			case "reveal_symlink":
				if fsrv.Browse == nil {
					return nil, h.Err("reveal_symlink subdirectove requires browsing to be enabled")
				}
				fsrv.Browse.RevealSymlink = true

			case "precompressed":
				var order []string
				for h.NextArg() {
					modID := "http.precompressed." + h.Val()
					mod, err := caddy.GetModule(modID)
					if err != nil {
						return nil, h.Errf("getting module named '%s': %v", modID, err)
					}
					inst := mod.New()
					precompress, ok := inst.(encode.Precompressed)
					if !ok {
						return nil, h.Errf("module %s is not a precompressor; is %T", modID, inst)
					}
					if fsrv.PrecompressedRaw == nil {
						fsrv.PrecompressedRaw = make(caddy.ModuleMap)
					}
					fsrv.PrecompressedRaw[h.Val()] = caddyconfig.JSON(precompress, nil)
					order = append(order, h.Val())
				}
				fsrv.PrecompressedOrder = order

			case "status":
				if !h.NextArg() {
					return nil, h.ArgErr()
				}
				fsrv.StatusCode = caddyhttp.WeakString(h.Val())

			case "disable_canonical_uris":
				if h.NextArg() {
					return nil, h.ArgErr()
				}
				falseBool := false
				fsrv.CanonicalURIs = &falseBool


Review comment (suggestion):
I actually think this should be a subdirective of `browse` -- like within a block. Since it can't be used without it. Then it also has structure parity with the JSON config.

Code after:
			fsrv.IndexNames = d.RemainingArgs()
			if len(fsrv.IndexNames) == 0 {
				return d.ArgErr()
			}

		case "root":
			if !d.Args(&fsrv.Root) {
				return d.ArgErr()
			}

		case "browse":
			if fsrv.Browse != nil {
				return d.Err("browsing is already configured")
			}
			fsrv.Browse = new(Browse)
			d.Args(&fsrv.Browse.TemplateFile)
			for nesting := d.Nesting(); d.NextBlock(nesting); {
				if d.Val() != "reveal_symlinks" {
					return d.Errf("unknown subdirective '%s'", d.Val())
				}
				if fsrv.Browse.RevealSymlinks {
					return d.Err("Symlinks path reveal is already enabled")
				}
				fsrv.Browse.RevealSymlinks = true
			}

		case "precompressed":
			var order []string
			for d.NextArg() {
				modID := "http.precompressed." + d.Val()
				mod, err := caddy.GetModule(modID)
				if err != nil {
					return d.Errf("getting module named '%s': %v", modID, err)
				}
				inst := mod.New()
				precompress, ok := inst.(encode.Precompressed)
				if !ok {
					return d.Errf("module %s is not a precompressor; is %T", modID, inst)
				}
				if fsrv.PrecompressedRaw == nil {
					fsrv.PrecompressedRaw = make(caddy.ModuleMap)
				}
				fsrv.PrecompressedRaw[d.Val()] = caddyconfig.JSON(precompress, nil)
				order = append(order, d.Val())
			}
			fsrv.PrecompressedOrder = order

		case "status":
			if !d.NextArg() {
				return d.ArgErr()
			}
Repository: caddyserver/caddy
File: modules/caddyhttp/fileserver/browsetplcontext.go (Go)

Code before:
		limit, _ := strconv.Atoi(limitParam)

		if limit > 0 && limit <= len(l.Items) {
			l.Items = l.Items[:limit]
			l.Limit = limit
		}
	}
}

// crumb represents part of a breadcrumb menu,
// pairing a link with the text to display.
type crumb struct {
	Link, Text string
}

// fileInfo contains serializable information
// about a file or directory.
type fileInfo struct {
	Name        string      `json:"name"`
	Size        int64       `json:"size"`
	URL         string      `json:"url"`
	ModTime     time.Time   `json:"mod_time"`
	Mode        os.FileMode `json:"mode"`
	IsDir       bool        `json:"is_dir"`
	IsSymlink   bool        `json:"is_symlink"`
	SymlinkPath string      `json:"symlink_path"`

	// a pointer to the template context is useful inside nested templates
	Tpl *browseTemplateContext `json:"-"`
}

// HasExt returns true if the filename has any of the given suffixes, case-insensitive.
func (fi fileInfo) HasExt(exts ...string) bool {
	for _, ext := range exts {
		if strings.HasSuffix(strings.ToLower(fi.Name), strings.ToLower(ext)) {
			return true
		}
	}
	return false
}

// HumanSize returns the size of the file as a
// human-readable string in IEC format (i.e.
// power of 2 or base 1024).
func (fi fileInfo) HumanSize() string {
	return humanize.IBytes(uint64(fi.Size))
}

// HumanTotalFileSize returns the total size of all files
// in the listing as a human-readable string in IEC format
// (i.e. power of 2 or base 1024).

Review comment (suggestion):
```suggestion
	SymlinkPath string      `json:"symlink_path,omitempty"`
```
Just a quick little change, I'll merge this in a sec

Code after:
		limit, _ := strconv.Atoi(limitParam)

		if limit > 0 && limit <= len(l.Items) {
			l.Items = l.Items[:limit]
			l.Limit = limit
		}
	}
}

// crumb represents part of a breadcrumb menu,
// pairing a link with the text to display.
type crumb struct {
	Link, Text string
}

// fileInfo contains serializable information
// about a file or directory.
type fileInfo struct {
	Name        string      `json:"name"`
	Size        int64       `json:"size"`
	URL         string      `json:"url"`
	ModTime     time.Time   `json:"mod_time"`
	Mode        os.FileMode `json:"mode"`
	IsDir       bool        `json:"is_dir"`
	IsSymlink   bool        `json:"is_symlink"`
	SymlinkPath string      `json:"symlink_path,omitempty"`

	// a pointer to the template context is useful inside nested templates
	Tpl *browseTemplateContext `json:"-"`
}

// HasExt returns true if the filename has any of the given suffixes, case-insensitive.
func (fi fileInfo) HasExt(exts ...string) bool {
	for _, ext := range exts {
		if strings.HasSuffix(strings.ToLower(fi.Name), strings.ToLower(ext)) {
			return true
		}
	}
	return false
}

// HumanSize returns the size of the file as a
// human-readable string in IEC format (i.e.
// power of 2 or base 1024).
func (fi fileInfo) HumanSize() string {
	return humanize.IBytes(uint64(fi.Size))
}

// HumanTotalFileSize returns the total size of all files
// in the listing as a human-readable string in IEC format
// (i.e. power of 2 or base 1024).
Repository: caddyserver/caddy
File: logging.go (Go)

Code before:
		cl.levelEnabler = zapcore.InfoLevel
	case "warn":
		cl.levelEnabler = zapcore.WarnLevel
	case "error":
		cl.levelEnabler = zapcore.ErrorLevel
	case "panic":
		cl.levelEnabler = zapcore.PanicLevel
	case "fatal":
		cl.levelEnabler = zapcore.FatalLevel
	default:
		return fmt.Errorf("unrecognized log level: %s", cl.Level)
	}

	if cl.EncoderRaw != nil {
		mod, err := ctx.LoadModule(cl, "EncoderRaw")
		if err != nil {
			return fmt.Errorf("loading log encoder module: %v", err)
		}
		cl.encoder = mod.(zapcore.Encoder)

		// if the encoder module needs the writer to determine
		// the correct default to use for a nested encoder, we
		// pass it down as a secondary provisioning step
		if cfd, ok := mod.(ConfiguresFormatterDefault); ok {
			err := cfd.ConfigureDefaultFormat(cl.writerOpener)
			if err != nil {
				return fmt.Errorf("configuring default format for encoder module: %v", err)
			}
		}
	}
	if cl.encoder == nil {
		cl.encoder = newDefaultProductionLogEncoder(cl.writerOpener)
	}
	cl.buildCore()
	return nil
}

func (cl *BaseLog) buildCore() {
	// logs which only discard their output don't need
	// to perform encoding or any other processing steps
	// at all, so just shorcut to a nop core instead
	if _, ok := cl.writerOpener.(*DiscardWriter); ok {
		cl.core = zapcore.NewNopCore()
		return
	}
	c := zapcore.NewCore(
		cl.encoder,
		zapcore.AddSync(cl.writer),
		cl.levelEnabler,
	)
	if cl.Sampling != nil {

Review comment (suggestion):
Nit, could be:

```suggestion
			if err := cfd.ConfigureDefaultFormat(cl.writerOpener); err != nil {
```


Code after:
	if cl.WriterRaw != nil {
		mod, err := ctx.LoadModule(cl, "WriterRaw")
		if err != nil {
			return fmt.Errorf("loading log writer module: %v", err)
		}
		cl.writerOpener = mod.(WriterOpener)
	}
	if cl.writerOpener == nil {
		cl.writerOpener = StderrWriter{}
	}
	var err error
	cl.writer, _, err = logging.openWriter(cl.writerOpener)
	if err != nil {
		return fmt.Errorf("opening log writer using %#v: %v", cl.writerOpener, err)
	}

	// set up the log level
	cl.levelEnabler, err = parseLevel(cl.Level)
	if err != nil {
		return err
	}

	if cl.EncoderRaw != nil {
		mod, err := ctx.LoadModule(cl, "EncoderRaw")
		if err != nil {
			return fmt.Errorf("loading log encoder module: %v", err)
		}
		cl.encoder = mod.(zapcore.Encoder)

		// if the encoder module needs the writer to determine
		// the correct default to use for a nested encoder, we
		// pass it down as a secondary provisioning step
		if cfd, ok := mod.(ConfiguresFormatterDefault); ok {
			if err := cfd.ConfigureDefaultFormat(cl.writerOpener); err != nil {
				return fmt.Errorf("configuring default format for encoder module: %v", err)
			}
		}
	}
	if cl.encoder == nil {
		cl.encoder = newDefaultProductionLogEncoder(cl.writerOpener)
	}
	cl.buildCore()
	return nil
}

func (cl *BaseLog) buildCore() {
	// logs which only discard their output don't need
	// to perform encoding or any other processing steps
	// at all, so just shorcut to a nop core instead
	if _, ok := cl.writerOpener.(*DiscardWriter); ok {
		cl.core = zapcore.NewNopCore()
Repository: caddyserver/caddy
File: modules/logging/filterencoder.go (Go)

Code before:

	// used to keep keys unique across nested objects
	keyPrefix string

	wrappedIsDefault bool
	ctx              caddy.Context
}

// CaddyModule returns the Caddy module information.
func (FilterEncoder) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "caddy.logging.encoders.filter",
		New: func() caddy.Module { return new(FilterEncoder) },
	}
}

// Provision sets up the encoder.
func (fe *FilterEncoder) Provision(ctx caddy.Context) error {
	fe.ctx = ctx

	if fe.WrappedRaw == nil {
		// if wrap is not specified, default to JSON
		fe.wrapped = &JSONEncoder{}
		if p, ok := fe.wrapped.(caddy.Provisioner); ok {
			err := p.Provision(ctx)
			if err != nil {
				return fmt.Errorf("provisioning fallback encoder module: %v", err)
			}
		}
		fe.wrappedIsDefault = true
	} else {
		// set up wrapped encoder
		val, err := ctx.LoadModule(fe, "WrappedRaw")
		if err != nil {
			return fmt.Errorf("loading fallback encoder module: %v", err)
		}
		fe.wrapped = val.(zapcore.Encoder)
	}

	// set up each field filter
	if fe.Fields == nil {
		fe.Fields = make(map[string]LogFieldFilter)
	}
	vals, err := ctx.LoadModule(fe, "FieldsRaw")
	if err != nil {
		return fmt.Errorf("loading log filter modules: %v", err)
	}
	for fieldName, modIface := range vals.(map[string]any) {
		fe.Fields[fieldName] = modIface.(LogFieldFilter)
	}


Review comment (suggestion):
Same here:

```suggestion
			if err := p.Provision(ctx); err != nil {
```


Code after:

	// used to keep keys unique across nested objects
	keyPrefix string

	wrappedIsDefault bool
	ctx              caddy.Context
}

// CaddyModule returns the Caddy module information.
func (FilterEncoder) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "caddy.logging.encoders.filter",
		New: func() caddy.Module { return new(FilterEncoder) },
	}
}

// Provision sets up the encoder.
func (fe *FilterEncoder) Provision(ctx caddy.Context) error {
	fe.ctx = ctx

	if fe.WrappedRaw == nil {
		// if wrap is not specified, default to JSON
		fe.wrapped = &JSONEncoder{}
		if p, ok := fe.wrapped.(caddy.Provisioner); ok {
			if err := p.Provision(ctx); err != nil {
				return fmt.Errorf("provisioning fallback encoder module: %v", err)
			}
		}
		fe.wrappedIsDefault = true
	} else {
		// set up wrapped encoder
		val, err := ctx.LoadModule(fe, "WrappedRaw")
		if err != nil {
			return fmt.Errorf("loading fallback encoder module: %v", err)
		}
		fe.wrapped = val.(zapcore.Encoder)
	}

	// set up each field filter
	if fe.Fields == nil {
		fe.Fields = make(map[string]LogFieldFilter)
	}
	vals, err := ctx.LoadModule(fe, "FieldsRaw")
	if err != nil {
		return fmt.Errorf("loading log filter modules: %v", err)
	}
	for fieldName, modIface := range vals.(map[string]any) {
		fe.Fields[fieldName] = modIface.(LogFieldFilter)
	}

	return nil
Repository: caddyserver/caddy
File: modules/logging/filterencoder.go (Go)

Code before:
		return fmt.Errorf("loading log filter modules: %v", err)
	}
	for fieldName, modIface := range vals.(map[string]any) {
		fe.Fields[fieldName] = modIface.(LogFieldFilter)
	}

	return nil
}

// ConfigureDefaultFormat will set the default format to "console"
// if the writer is a terminal. If already configured as a filter
// encoder, it passes through the writer so a deeply nested filter
// encoder can configure its own default format.
func (fe *FilterEncoder) ConfigureDefaultFormat(wo caddy.WriterOpener) error {
	if !fe.wrappedIsDefault {
		if cfd, ok := fe.wrapped.(caddy.ConfiguresFormatterDefault); ok {
			return cfd.ConfigureDefaultFormat(wo)
		}
		return nil
	}

	if caddy.IsWriterStandardStream(wo) && term.IsTerminal(int(os.Stderr.Fd())) {
		fe.wrapped = &ConsoleEncoder{}
		if p, ok := fe.wrapped.(caddy.Provisioner); ok {
			err := p.Provision(fe.ctx)
			if err != nil {
				return fmt.Errorf("provisioning fallback encoder module: %v", err)
			}
		}
	}
	return nil
}

// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax:
//
//	filter {
//	    wrap <another encoder>
//	    fields {
//	        <field> <filter> {
//	            <filter options>
//	        }
//	    }
//	}
func (fe *FilterEncoder) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
	for d.Next() {
		for d.NextBlock(0) {
			switch d.Val() {
			case "wrap":
				if !d.NextArg() {
					return d.ArgErr()
				}

Review comment (suggestion):
```suggestion
			if err := p.Provision(fe.ctx) ; err != nil {
```


Code after:
	}
	for fieldName, modIface := range vals.(map[string]any) {
		fe.Fields[fieldName] = modIface.(LogFieldFilter)
	}

	return nil
}

// ConfigureDefaultFormat will set the default format to "console"
// if the writer is a terminal. If already configured as a filter
// encoder, it passes through the writer so a deeply nested filter
// encoder can configure its own default format.
func (fe *FilterEncoder) ConfigureDefaultFormat(wo caddy.WriterOpener) error {
	if !fe.wrappedIsDefault {
		if cfd, ok := fe.wrapped.(caddy.ConfiguresFormatterDefault); ok {
			return cfd.ConfigureDefaultFormat(wo)
		}
		return nil
	}

	if caddy.IsWriterStandardStream(wo) && term.IsTerminal(int(os.Stderr.Fd())) {
		fe.wrapped = &ConsoleEncoder{}
		if p, ok := fe.wrapped.(caddy.Provisioner); ok {
			if err := p.Provision(fe.ctx); err != nil {
				return fmt.Errorf("provisioning fallback encoder module: %v", err)
			}
		}
	}
	return nil
}

// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax:
//
//	filter {
//	    wrap <another encoder>
//	    fields {
//	        <field> <filter> {
//	            <filter options>
//	        }
//	    }
//	}
func (fe *FilterEncoder) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
	d.Next() // consume encoder name
	for d.NextBlock(0) {
		switch d.Val() {
		case "wrap":
			if !d.NextArg() {
				return d.ArgErr()
			}
			moduleName := d.Val()
			moduleID := "caddy.logging.encoders." + moduleName