diff --git a/storage/conf.nim b/storage/conf.nim index bd0f6a2d..ca9f6c52 100644 --- a/storage/conf.nim +++ b/storage/conf.nim @@ -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:") -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() diff --git a/tests/storage/testconf.nim b/tests/storage/testconf.nim index 836135d5..a14b84ac 100644 --- a/tests/storage/testconf.nim +++ b/tests/storage/testconf.nim @@ -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")