Skip to content

Report configuration errors instead of printing them - #74

Merged
beetlebugorg merged 1 commit into
mainfrom
fix/config-error-reporting
Aug 27, 2026
Merged

beetlebugorg merged 1 commit into
mainfrom
fix/config-error-reporting

Conversation

@beetlebugorg

Copy link
Copy Markdown
Owner

Behaviour change: a deployment with a malformed setting that starts today will refuse to start after this.

Five init functions parsed environment settings, printed any failure with fmt.Printf, and carried on with a partly populated struct:

config = &Config{}
if err := env.Parse(config); err != nil {
	fmt.Printf("%+v\n", err)
}

Two problems followed.

A misconfigured deployment started anyway, on silent defaults. That matters most for DIMS_ALLOWED_SOURCE_BACKENDS, where the default is the narrow value and a typo would quietly widen or narrow what the service will fetch.

And these run before slog is configured in Run, so the messages bypassed DIMS_LOG_FORMAT=json entirely and arrived as bare stdout lines no log pipeline would parse. The one thing an operator needs to see was the one thing they could not search for.

The change

Failures are collected during initialisation and reported by Config.Validate, which serve already calls after logging is set up. errors.Join keeps all of them rather than only the first.

The five call sites move from fmt.Printf to RecordStartupError. encryption.go also stops using slog.Error for its key derivation failure, for the same reason: nothing is listening yet.

This deliberately avoids restructuring initialisation. Moving configuration loading out of init would change package initialisation order and when source backends register, which is a larger change than the problem needs.

Effect

$ DIMS_CACHE_CONTROL_MIN=notanumber dims serve
dims: error: invalid configuration: env: parse error on field "Min" of type "int": strconv.ParseInt: parsing "notanumber": invalid syntax

Previously that printed a similar line and started the server on defaults.

Tests

internal/core/config_test.go covers a recorded error surfacing through Validate, a clean configuration passing, an unknown DIMS_DEFAULT_OUTPUT_FORMAT being refused, and RecordStartupError ignoring nil. Each saves and restores the package state so ordering does not matter.

Verification

In ghcr.io/beetlebugorg/go-dims:builder: gofmt, go vet, and go test -race ./... all pass. The failure above is from the built binary.

- Collect environment parse failures during initialisation.
- Fail startup when any were recorded.
@beetlebugorg
beetlebugorg merged commit f77d0d2 into main Aug 27, 2026
3 checks passed
@beetlebugorg
beetlebugorg deleted the fix/config-error-reporting branch August 27, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant