chore: raise instead of quitting on an invalid config value (#1495)

Co-authored-by: gmega <giuliano.mega@gmail.com>
This commit is contained in:
Arnaud 2026-07-31 23:40:18 +04:00 committed by GitHub
parent 9943bded91
commit e3dfe5113c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 95 additions and 63 deletions

View File

@ -27,6 +27,7 @@ import pkg/chronicles/topics_registry
import pkg/confutils/defs
import pkg/confutils/std/net
import pkg/toml_serialization
import pkg/toml_serialization/lexer
import pkg/metrics
import pkg/metrics/chronos_httpserver
import pkg/stew/byteutils
@ -48,7 +49,8 @@ from ./blockexchange/engine/downloadmanager import DefaultBlockRetries
from ./dht_proxy/protocol import DefaultMaxInFlightLookups
export
units, net, storagetypes, logutils, presets, completeCmdArg, parseCmdArg, NatConfig
units, net, storagetypes, defs, logutils, presets, completeCmdArg, parseCmdArg,
NatConfig
export
DefaultQuotaBytes, DefaultBlockTtl, DefaultBlockInterval, DefaultNumBlocksPerInterval,
@ -494,19 +496,21 @@ const
proc parseCmdArg*(
T: typedesc[MultiAddress], input: string
): MultiAddress {.raises: [ValueError].} =
var ma: MultiAddress
try:
let res = MultiAddress.init(input)
if res.isOk:
ma = res.get()
else:
fatal "Invalid MultiAddress", input = input, error = res.error()
quit QuitFailure
except LPError as exc:
fatal "Invalid MultiAddress uri", uri = input, error = exc.msg
quit QuitFailure
ma
): MultiAddress {.raises: [ConfigurationError].} =
let res =
try:
MultiAddress.init(input)
except LPError as exc:
raise newException(
ConfigurationError, "Invalid MultiAddress uri " & input & ": " & exc.msg
)
if res.isErr:
raise newException(
ConfigurationError, "Invalid MultiAddress " & input & ": " & res.error()
)
res.get()
proc parse*(T: type ThreadCount, p: string): Result[ThreadCount, string] =
try:
@ -517,18 +521,22 @@ proc parse*(T: type ThreadCount, p: string): Result[ThreadCount, string] =
except ValueError as e:
return err("Invalid number of threads: " & p & ", error=" & e.msg)
proc parseCmdArg*(T: type ThreadCount, input: string): T =
proc parseCmdArg*(
T: type ThreadCount, input: string
): T {.raises: [ConfigurationError].} =
let val = ThreadCount.parse(input)
if val.isErr:
fatal "Cannot parse the thread count.", input = input, error = val.error()
quit QuitFailure
raise newException(ConfigurationError, val.error())
return val.get()
proc parseCmdArg*(T: type SignedPeerRecord, uri: string): T =
proc parseCmdArg*(
T: type SignedPeerRecord, uri: string
): T {.raises: [ConfigurationError].} =
let res = SignedPeerRecord.parse(uri)
if res.isErr:
fatal "Cannot parse the signed peer.", error = res.error(), input = uri
quit QuitFailure
raise newException(
ConfigurationError, "Cannot parse the signed peer " & uri & ": " & res.error()
)
return res.get()
func parse*(T: type NatConfig, p: string): Result[NatConfig, string] =
@ -546,11 +554,10 @@ func parse*(T: type NatConfig, p: string): Result[NatConfig, string] =
else:
return err("Not a valid NAT option: " & p & ". Valid options: auto, extip:<IP>")
proc parseCmdArg*(T: type NatConfig, p: string): T =
proc parseCmdArg*(T: type NatConfig, p: string): T {.raises: [ConfigurationError].} =
let res = NatConfig.parse(p)
if res.isErr:
fatal "Cannot parse the NAT config.", error = res.error(), input = p
quit QuitFailure
raise newException(ConfigurationError, res.error())
return res.get()
proc completeCmdArg*(T: type NatConfig, val: string): seq[string] =
@ -563,50 +570,44 @@ func parse*(T: type NBytes, p: string): Result[NBytes, string] =
return err("Invalid number of bytes: " & p)
return ok(NBytes(num))
proc parseCmdArg*(T: type NBytes, val: string): T =
proc parseCmdArg*(T: type NBytes, val: string): T {.raises: [ConfigurationError].} =
let res = NBytes.parse(val)
if res.isErr:
fatal "Cannot parse NBytes.", error = res.error(), input = val
quit QuitFailure
raise newException(ConfigurationError, res.error())
return res.get()
proc parseCmdArg*(T: type Duration, val: string): T =
proc parseCmdArg*(T: type Duration, val: string): T {.raises: [ConfigurationError].} =
var dur: Duration
let count = parseDuration(val, dur)
if count == 0:
fatal "Cannot parse duration", dur = dur
quit QuitFailure
raise newException(ConfigurationError, "Invalid duration: " & val)
dur
proc parseCmdArg*(T: type NetworkPreset, p: string): NetworkPreset =
proc parseCmdArg*(
T: type NetworkPreset, p: string
): NetworkPreset {.raises: [ConfigurationError].} =
let res = NetworkPresets.find(p)
if res.isNone:
fatal "Invalid network preset.", input = p
quit QuitFailure
raise newException(ConfigurationError, "Invalid network preset: " & p)
return res.get()
proc readValue*(r: var TomlReader, val: var SignedPeerRecord) =
without uri =? r.readValue(string).catch, err:
error "invalid SignedPeerRecord configuration value", error = err.msg
quit QuitFailure
proc readValue*(
r: var TomlReader, val: var SignedPeerRecord
) {.raises: [SerializationError, IOError].} =
let uri = r.readValue(string)
try:
val = SignedPeerRecord.parseCmdArg(uri)
except LPError as err:
fatal "Invalid SignedPeerRecord uri", uri = uri, error = err.msg
quit QuitFailure
except CatchableError as err:
r.lex.raiseTomlErr(err.msg)
proc readValue*(r: var TomlReader, val: var MultiAddress) =
without input =? r.readValue(string).catch, err:
error "invalid MultiAddress configuration value", error = err.msg
quit QuitFailure
let res = MultiAddress.init(input)
if res.isOk:
val = res.get()
else:
fatal "Invalid MultiAddress", input = input, error = res.error()
quit QuitFailure
proc readValue*(
r: var TomlReader, val: var MultiAddress
) {.raises: [SerializationError, IOError].} =
let input = r.readValue(string)
try:
val = MultiAddress.parseCmdArg(input)
except CatchableError as err:
r.lex.raiseTomlErr(err.msg)
proc readValue*(
r: var TomlReader, val: var NBytes
@ -615,8 +616,7 @@ proc readValue*(
var str = r.readValue(string)
let count = parseSize(str, value, alwaysBin = true)
if count == 0:
error "invalid number of bytes for configuration value", value = str
quit QuitFailure
r.lex.raiseTomlErr("Invalid number of bytes: " & str)
val = NBytes(value)
proc readValue*(
@ -626,7 +626,7 @@ proc readValue*(
try:
val = parseCmdArg(ThreadCount, str)
except CatchableError as err:
raise newException(SerializationError, err.msg)
r.lex.raiseTomlErr(err.msg)
proc readValue*(
r: var TomlReader, val: var Duration
@ -635,18 +635,17 @@ proc readValue*(
var dur: Duration
let count = parseDuration(str, dur)
if count == 0:
error "Invalid duration parse", value = str
quit QuitFailure
r.lex.raiseTomlErr("Invalid duration: " & str)
val = dur
proc readValue*(
r: var TomlReader, val: var NatConfig
) {.raises: [SerializationError].} =
val =
try:
parseCmdArg(NatConfig, r.readValue(string))
except CatchableError as err:
raise newException(SerializationError, err.msg)
) {.raises: [SerializationError, IOError].} =
let str = r.readValue(string)
try:
val = parseCmdArg(NatConfig, str)
except CatchableError as err:
r.lex.raiseTomlErr(err.msg)
proc readValue*(
r: var TomlReader, val: var NetworkPreset
@ -655,7 +654,7 @@ proc readValue*(
str = r.readValue(string)
preset = NetworkPresets.find(str)
if preset.isNone:
raise newException(SerializationError, "Invalid network preset: " & str)
r.lex.raiseTomlErr("Invalid network preset: " & str)
val = preset.get()

View File

@ -147,3 +147,36 @@ suite "Conf - validateAutonatConfig":
config.natPortMappingRecheckPeriod = 0
check config.validateAutonatConfig().isErr
suite "Conf - parseCmdArg":
test "rejects an invalid NAT config":
expect ConfigurationError:
discard parseCmdArg(NatConfig, "none")
test "rejects an invalid thread count":
expect ConfigurationError:
discard parseCmdArg(ThreadCount, "abc")
test "rejects a thread count below two":
expect ConfigurationError:
discard parseCmdArg(ThreadCount, "1")
test "rejects an invalid duration":
expect ConfigurationError:
discard parseCmdArg(Duration, "forever")
test "rejects an invalid number of bytes":
expect ConfigurationError:
discard parseCmdArg(NBytes, "many")
test "rejects an invalid network preset":
expect ConfigurationError:
discard parseCmdArg(NetworkPreset, "unknown")
test "rejects an invalid multiaddress":
expect ConfigurationError:
discard parseCmdArg(MultiAddress, "not-a-multiaddress")
test "rejects an invalid signed peer record":
expect ConfigurationError:
discard parseCmdArg(SignedPeerRecord, "not-an-spr")