mirror of
https://github.com/fatedier/frp.git
synced 2026-03-21 01:09:27 +08:00
pkg/config: improve error messages with line number details for config parsing (#5194)
When frpc verify encounters config errors, the error messages now include line/column information to help users locate problems: - TOML syntax errors: report line and column from the TOML parser (e.g., "toml: line 4, column 11: expected character ]") - Type mismatch errors: report the field name and approximate line number (e.g., "line 3: field \"proxies\": cannot unmarshal string into ...") - File format detection: use file extension to determine format, preventing silent fallthrough from TOML to YAML parser which produced confusing errors Previously, a TOML file with syntax errors would silently fall through to the YAML parser, which would misinterpret the content and produce unhelpful errors like "json: cannot unmarshal string into Go value of type v1.ClientConfig". https://claude.ai/code/session_017HWLfcXS3U2hLoy4dsg8Nv Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -495,3 +495,109 @@ serverPort: 7000
|
||||
require.Equal("127.0.0.1", clientCfg.ServerAddr)
|
||||
require.Equal(7000, clientCfg.ServerPort)
|
||||
}
|
||||
|
||||
func TestTOMLSyntaxErrorWithLineNumber(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
// TOML with syntax error (unclosed table array header)
|
||||
content := `serverAddr = "127.0.0.1"
|
||||
serverPort = 7000
|
||||
|
||||
[[proxies]
|
||||
name = "test"
|
||||
`
|
||||
|
||||
clientCfg := v1.ClientConfig{}
|
||||
err := LoadConfigure([]byte(content), &clientCfg, false, "toml")
|
||||
require.Error(err)
|
||||
require.Contains(err.Error(), "line")
|
||||
require.Contains(err.Error(), "toml")
|
||||
}
|
||||
|
||||
func TestTOMLTypeMismatchErrorWithFieldInfo(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
// TOML with wrong type: proxies should be a table array, not a string
|
||||
content := `serverAddr = "127.0.0.1"
|
||||
serverPort = 7000
|
||||
proxies = "this should be a table array"
|
||||
`
|
||||
|
||||
clientCfg := v1.ClientConfig{}
|
||||
err := LoadConfigure([]byte(content), &clientCfg, false, "toml")
|
||||
require.Error(err)
|
||||
// The error should contain field info
|
||||
errMsg := err.Error()
|
||||
require.Contains(errMsg, "proxies")
|
||||
}
|
||||
|
||||
func TestFindFieldLineInContent(t *testing.T) {
|
||||
content := []byte(`serverAddr = "127.0.0.1"
|
||||
serverPort = 7000
|
||||
|
||||
[[proxies]]
|
||||
name = "test"
|
||||
type = "tcp"
|
||||
remotePort = 6000
|
||||
`)
|
||||
|
||||
tests := []struct {
|
||||
fieldPath string
|
||||
wantLine int
|
||||
}{
|
||||
{"serverAddr", 1},
|
||||
{"serverPort", 2},
|
||||
{"name", 5},
|
||||
{"type", 6},
|
||||
{"remotePort", 7},
|
||||
{"nonexistent", 0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.fieldPath, func(t *testing.T) {
|
||||
got := findFieldLineInContent(content, tt.fieldPath)
|
||||
require.Equal(t, tt.wantLine, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatDetection(t *testing.T) {
|
||||
tests := []struct {
|
||||
path string
|
||||
format string
|
||||
}{
|
||||
{"config.toml", "toml"},
|
||||
{"config.TOML", "toml"},
|
||||
{"config.yaml", "yaml"},
|
||||
{"config.yml", "yaml"},
|
||||
{"config.json", "json"},
|
||||
{"config.ini", ""},
|
||||
{"config", ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.path, func(t *testing.T) {
|
||||
require.Equal(t, tt.format, detectFormatFromPath(tt.path))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidTOMLStillWorks(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
// Valid TOML with format hint should work fine
|
||||
content := `serverAddr = "127.0.0.1"
|
||||
serverPort = 7000
|
||||
|
||||
[[proxies]]
|
||||
name = "test"
|
||||
type = "tcp"
|
||||
remotePort = 6000
|
||||
`
|
||||
clientCfg := v1.ClientConfig{}
|
||||
err := LoadConfigure([]byte(content), &clientCfg, false, "toml")
|
||||
require.NoError(err)
|
||||
require.Equal("127.0.0.1", clientCfg.ServerAddr)
|
||||
require.Equal(7000, clientCfg.ServerPort)
|
||||
require.Len(clientCfg.Proxies, 1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user