@marcel91200 / caddy Mirror · read-only / commits / d269405e
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 17:15 UTC

core: Show JSON error offsets where possible (#7437)

Francis Lavoie committed Jan 14, 2026 at 22:54 UTC d269405eabf30250283c271c4ff6095a2c5ded2c
4 files changed +18 -4
admin.go
+4 -1
@@ -1110,7 +1110,10 @@ func unsyncedConfigAccess(method, path string, body []byte, out io.Writer) error
1110 if len(body) > 0 {
1111 err = json.Unmarshal(body, &val)
1112 if err != nil {
1113 - return fmt.Errorf("decoding request body: %v", err)
1113 + if jsonErr, ok := err.(*json.SyntaxError); ok {
1114 + return fmt.Errorf("decoding request body: %w, at offset %d", jsonErr, jsonErr.Offset)
1115 + }
1116 + return fmt.Errorf("decoding request body: %w", err)
1117 }
1118 }
1119
caddyconfig/configadapters.go
+5 -1
@@ -81,7 +81,11 @@ func JSONModuleObject(val any, fieldName, fieldVal string, warnings *[]Warning)
81 err = json.Unmarshal(enc, &tmp)
82 if err != nil {
83 if warnings != nil {
84 - *warnings = append(*warnings, Warning{Message: err.Error()})
84 + message := err.Error()
85 + if jsonErr, ok := err.(*json.SyntaxError); ok {
86 + message = fmt.Sprintf("%v, at offset %d", jsonErr.Error(), jsonErr.Offset)
87 + }
88 + *warnings = append(*warnings, Warning{Message: message})
89 }
90 return nil
91 }
cmd/main.go
+4 -1
@@ -231,7 +231,10 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
231 // validate that the config is at least valid JSON
232 err = json.Unmarshal(config, new(any))
233 if err != nil {
234 - return nil, "", "", fmt.Errorf("config is not valid JSON: %v; did you mean to use a config adapter (the --adapter flag)?", err)
234 + if jsonErr, ok := err.(*json.SyntaxError); ok {
235 + return nil, "", "", fmt.Errorf("config is not valid JSON: %w, at offset %d; did you mean to use a config adapter (the --adapter flag)?", err, jsonErr.Offset)
236 + }
237 + return nil, "", "", fmt.Errorf("config is not valid JSON: %w; did you mean to use a config adapter (the --adapter flag)?", err)
238 }
239 }
240
modules.go
+5 -1
@@ -342,7 +342,11 @@ func ParseStructTag(tag string) (map[string]string, error) {
342 func StrictUnmarshalJSON(data []byte, v any) error {
343 dec := json.NewDecoder(bytes.NewReader(data))
344 dec.DisallowUnknownFields()
345 - return dec.Decode(v)
345 + err := dec.Decode(v)
346 + if jsonErr, ok := err.(*json.SyntaxError); ok {
347 + return fmt.Errorf("%w, at offset %d", jsonErr, jsonErr.Offset)
348 + }
349 + return err
350 }
351
352 var JSONRawMessageType = reflect.TypeFor[json.RawMessage]()