diff --git a/questionable/private/binderror.nim b/questionable/private/binderror.nim index 9af77ad..5154e37 100644 --- a/questionable/private/binderror.nim +++ b/questionable/private/binderror.nim @@ -1,15 +1,15 @@ import std/options -var captureEnabled {.global, compileTime.}: bool +var captures {.global, compileTime.}: int var errorVariable: ptr ref CatchableError template captureBindError*(error: var ref CatchableError, expression): auto = let previousErrorVariable = errorVariable errorVariable = addr error - static: captureEnabled = true + static: inc captures let evaluated = expression - static: captureEnabled = false + static: dec captures errorVariable = previousErrorVariable @@ -19,6 +19,6 @@ func error[T](option: Option[T]): ref CatchableError = newException(ValueError, "Option is set to `none`") template bindFailed*(expression) = - when captureEnabled: + when captures > 0: mixin error errorVariable[] = expression.error diff --git a/testmodules/result/test.nim b/testmodules/result/test.nim index 94ed4c7..21b9bfc 100644 --- a/testmodules/result/test.nim +++ b/testmodules/result/test.nim @@ -294,6 +294,22 @@ suite "result": foo() + test "without statement with error works in nested generic calls": + proc works(_: type int): ?!int = + without _ =? int.failure "error1", err: + return success 42 + + proc fails(_: type int): ?!int = + return failure "error2" + + proc foo = + without a =? int.works() and b =? int.fails(), error: + check error.msg == "error2" + return + fail() + + foo() + test "catch can be used to convert exceptions to results": check parseInt("42").catch == 42.success check parseInt("foo").catch.error of ValueError