diff options
Diffstat (limited to 'tests/exception')
33 files changed, 1142 insertions, 0 deletions
diff --git a/tests/exception/m21261.nim b/tests/exception/m21261.nim new file mode 100644 index 000000000..11b12fb5b --- /dev/null +++ b/tests/exception/m21261.nim @@ -0,0 +1 @@ +raise (ref Exception)(msg: "something") \ No newline at end of file diff --git a/tests/exception/m22469.nim b/tests/exception/m22469.nim new file mode 100644 index 000000000..201698701 --- /dev/null +++ b/tests/exception/m22469.nim @@ -0,0 +1,4 @@ +# ModuleB +echo "First top-level statement of ModuleB" +echo high(int) + 1 +echo "ModuleB last statement" \ No newline at end of file diff --git a/tests/exception/t13115.nim b/tests/exception/t13115.nim new file mode 100644 index 000000000..5db8f9107 --- /dev/null +++ b/tests/exception/t13115.nim @@ -0,0 +1,31 @@ +const msg = "This char is `" & '\0' & "` and works fine!" + +when defined nim_t13115: + # bug #13115 + template fn = + raise newException(Exception, msg) + when defined nim_t13115_static: + static: fn() + fn() +else: + import std/[osproc,strformat,os,strutils] + proc main = + const nim = getCurrentCompilerExe() + const file = currentSourcePath + for b in "c js cpp".split: + # save CI time by avoiding mostly redundant combinations as far as this bug is concerned + var opts = case b + of "c": @["", "-d:nim_t13115_static", "-d:danger", "-d:debug"] + of "js": @["", "-d:nim_t13115_static"] + else: @[""] + + for opt in opts: + let cmd = fmt"{nim} r -b:{b} -d:nim_t13115 {opt} --hints:off {file}" + let (outp, exitCode) = execCmdEx(cmd) + when defined windows: + # `\0` not preserved on windows + doAssert "` and works fine!" in outp, cmd & "\n" & msg + else: + doAssert msg in outp, cmd & "\n" & msg + doAssert exitCode == 1 + main() diff --git a/tests/exception/t18620.nim b/tests/exception/t18620.nim new file mode 100644 index 000000000..ee23f8bac --- /dev/null +++ b/tests/exception/t18620.nim @@ -0,0 +1,17 @@ +discard """ + matrix: "--gc:arc; --gc:refc" +""" + +proc hello() = + raise newException(ValueError, "You are wrong") + +var flag = false + +try: + hello() +except ValueError as e: + flag = true + doAssert len(getStackTraceEntries(e)) > 0 + doAssert len(getStackTraceEntries(e)) > 0 + +doAssert flag diff --git a/tests/exception/t20613.nim b/tests/exception/t20613.nim new file mode 100644 index 000000000..6edb69415 --- /dev/null +++ b/tests/exception/t20613.nim @@ -0,0 +1,8 @@ +discard """ + matrix: "; --panics:on" +""" + +func test = + if 0 > 10: + raiseAssert "hey" +test() diff --git a/tests/exception/t21261.nim b/tests/exception/t21261.nim new file mode 100644 index 000000000..84817d854 --- /dev/null +++ b/tests/exception/t21261.nim @@ -0,0 +1,9 @@ +discard """ + exitcode: 1 + outputsub: ''' +m21261.nim(1) m21261 +Error: unhandled exception: something [Exception] +''' +""" + +import m21261 \ No newline at end of file diff --git a/tests/exception/t22008.nim b/tests/exception/t22008.nim new file mode 100644 index 000000000..c0758e7b4 --- /dev/null +++ b/tests/exception/t22008.nim @@ -0,0 +1,8 @@ +template detect(v: untyped) = + doAssert typeof(v) is int + +detect: + try: + raise (ref ValueError)() + except ValueError: + 42 \ No newline at end of file diff --git a/tests/exception/t22469.nim b/tests/exception/t22469.nim new file mode 100644 index 000000000..a76c74967 --- /dev/null +++ b/tests/exception/t22469.nim @@ -0,0 +1,16 @@ +discard """ + exitcode: 1 + output: ''' +First top-level statement of ModuleB +m22469.nim(3) m22469 +fatal.nim(53) sysFatal +Error: unhandled exception: over- or underflow [OverflowDefect] +''' +""" + +# bug #22469 + +# ModuleA +import m22469 +echo "ModuleA about to have exception" +echo high(int) + 1 diff --git a/tests/exception/t9657.nim b/tests/exception/t9657.nim new file mode 100644 index 000000000..6ac525a70 --- /dev/null +++ b/tests/exception/t9657.nim @@ -0,0 +1,12 @@ +discard """ + action: run + exitcode: 1 + targets: "c cpp" + disabled: "openbsd" + disabled: "netbsd" +""" + +close stdmsg +const m = "exception!" +# see #10343 for details on this test +discard writeBuffer(stdmsg, cstring(m), m.len) diff --git a/tests/exception/tcontinuexc.nim b/tests/exception/tcontinuexc.nim new file mode 100644 index 000000000..b7560a605 --- /dev/null +++ b/tests/exception/tcontinuexc.nim @@ -0,0 +1,26 @@ +discard """ + outputsub: "ECcaught" + exitcode: "1" +""" +type + ESomething = object of Exception + ESomeOtherErr = object of Exception + +proc genErrors(s: string) = + if s == "error!": + raise newException(ESomething, "Test") + else: + raise newException(EsomeotherErr, "bla") + +try: + for i in 0..3: + try: + genErrors("error!") + except ESomething: + stdout.write("E") + stdout.write("C") + raise newException(EsomeotherErr, "bla") +finally: + echo "caught" + +#OUT ECcaught diff --git a/tests/exception/tcpp_imported_exc.nim b/tests/exception/tcpp_imported_exc.nim new file mode 100644 index 000000000..55a58440f --- /dev/null +++ b/tests/exception/tcpp_imported_exc.nim @@ -0,0 +1,136 @@ +discard """ +matrix: "--mm:refc" +targets: "cpp" +output: ''' +caught as std::exception +expected +finally1 +finally2 +finally2 +2 +expected +finally 1 +finally 2 +expected +cpp exception caught +''' +disabled: "windows" # pending bug #18011 +""" + +type + std_exception* {.importcpp: "std::exception", header: "<exception>".} = object + std_runtime_error* {.importcpp: "std::runtime_error", header: "<stdexcept>".} = object + std_string* {.importcpp: "std::string", header: "<string>".} = object + +proc constructStdString(s: cstring): std_string {.importcpp: "std::string(@)", constructor, header: "<string>".} + +proc constructRuntimeError(s: stdstring): std_runtime_error {.importcpp: "std::runtime_error(@)", constructor.} + +proc what(ex: std_runtime_error): cstring {.importcpp: "((char *)#.what())".} + +proc myexception = + raise constructRuntimeError(constructStdString("cpp_exception")) + +try: + myexception() # raise std::runtime_error +except std_exception: + echo "caught as std::exception" + try: + raise constructStdString("x") + except std_exception: + echo "should not happen" + except: + echo "expected" + +doAssert(getCurrentException() == nil) + +proc earlyReturn = + try: + try: + myexception() + finally: + echo "finally1" + except: + return + finally: + echo "finally2" + +earlyReturn() +doAssert(getCurrentException() == nil) + + +try: + block blk1: + try: + raise newException(ValueError, "mmm") + except: + break blk1 +except: + echo "should not happen" +finally: + echo "finally2" + +doAssert(getCurrentException() == nil) + +#-------------------------------------- + +# raise by pointer and also generic type + +type + std_vector[T] {.importcpp"std::vector", header"<vector>".} = object + +proc newVector[T](len: int): ptr std_vector[T] {.importcpp: "new std::vector<'1>(@)".} +proc deleteVector[T](v: ptr std_vector[T]) {.importcpp: "delete @; @ = NIM_NIL;".} +proc len[T](v: std_vector[T]): uint {.importcpp: "size".} + +var v = newVector[int](2) +try: + try: + try: + raise v + except ptr std_vector[int] as ex: + echo len(ex[]) + raise newException(ValueError, "msg5") + except: + echo "should not happen" + finally: + deleteVector(v) +except: + echo "expected" + +doAssert(v == nil) +doAssert(getCurrentException() == nil) + +#-------------------------------------- + +# mix of Nim and imported exceptions +try: + try: + try: + raise newException(KeyError, "msg1") + except KeyError: + raise newException(ValueError, "msg2") + except: + echo "should not happen" + finally: + echo "finally 1" + except: + doAssert(getCurrentExceptionMsg() == "msg2") + raise constructStdString("std::string") + finally: + echo "finally 2" +except: + echo "expected" + +doAssert(getCurrentException() == nil) + +try: + try: + myexception() + except std_runtime_error as ex: + echo "cpp exception caught" + raise newException(ValueError, "rewritten " & $ex.what()) +except: + doAssert(getCurrentExceptionMsg() == "rewritten cpp_exception") + +doAssert(getCurrentException() == nil) diff --git a/tests/exception/tcpp_imported_exc2.nim b/tests/exception/tcpp_imported_exc2.nim new file mode 100644 index 000000000..ff299ea3d --- /dev/null +++ b/tests/exception/tcpp_imported_exc2.nim @@ -0,0 +1,10 @@ +discard """ +targets: "cpp" +output: "" +""" +#issue #14369 case 2 +type RuntimeError {.requiresInit, importcpp: "std::runtime_error", header: "<stdexcept>".} = object + +proc initRuntimeError(a: cstring): RuntimeError {.importcpp: "std::runtime_error(@)", constructor.} +try: raise initRuntimeError("foo2") +except: discard diff --git a/tests/exception/tdefer1.nim b/tests/exception/tdefer1.nim new file mode 100644 index 000000000..db46bad27 --- /dev/null +++ b/tests/exception/tdefer1.nim @@ -0,0 +1,35 @@ +discard """ + output: '''hi +1 +hi +2 +B +A''' +""" + +# bug #1742 + +import strutils +let x = try: parseInt("133a") + except: -1 + finally: echo "hi" + + +template atFuncEnd = + defer: + echo "A" + defer: + echo "B" + +template testB(): untyped = + let a = 0 + defer: echo "hi" + a + +proc main = + atFuncEnd() + echo 1 + let i = testB() + echo 2 + +main() diff --git a/tests/exception/tdont_overwrite_typename.nim b/tests/exception/tdont_overwrite_typename.nim new file mode 100644 index 000000000..d6dca0990 --- /dev/null +++ b/tests/exception/tdont_overwrite_typename.nim @@ -0,0 +1,30 @@ +discard """ + targets: "c cpp" + output: '''Check passed +Check passed''' +""" + +# bug #5628 + +proc checkException(ex: ref Exception) = + doAssert(ex.name == cstring"ValueError") + doAssert(ex.msg == "SecondException") + doAssert(ex.parent != nil) + doAssert(ex.parent.name == cstring"KeyError") + doAssert(ex.parent.msg == "FirstException") + echo "Check passed" + +var e: ref Exception +try: + try: + raise newException(KeyError, "FirstException") + except: + raise newException(ValueError, "SecondException", getCurrentException()) +except: + e = getCurrentException() + +try: + checkException(e) # passes here + raise e +except ValueError: + checkException(getCurrentException()) # fails here diff --git a/tests/exception/testindexerroroutput.nims b/tests/exception/testindexerroroutput.nims new file mode 100644 index 000000000..e282f14b4 --- /dev/null +++ b/tests/exception/testindexerroroutput.nims @@ -0,0 +1,23 @@ +mode = ScriptMode.Verbose + +case paramStr(3): + of "test1": + #543 + block: + let s = "abc" + discard s[len(s)] + of "test2": + #537 + block: + var s = "abc" + s[len(s)] = 'd' + of "test3": + #588 + block: + let arr = ['a', 'b', 'c'] + discard arr[len(arr)] + of "test4": + #588 + block: + var arr = ['a', 'b', 'c'] + arr[len(arr)] = 'd' diff --git a/tests/exception/texcas.nim b/tests/exception/texcas.nim new file mode 100644 index 000000000..ad6819f11 --- /dev/null +++ b/tests/exception/texcas.nim @@ -0,0 +1,43 @@ +discard """ + targets: "c cpp" + output: ''' +Hello +Hello +''' +""" +proc test[T]() = + try: + raise newException(T, "Hello") + except T as foobar: + echo(foobar.msg) + doAssert(not declared(foobar)) + +template testTemplate(excType: typedesc) = + try: + raise newException(excType, "Hello") + except excType as foobar: + echo(foobar.msg) + doAssert(not declared(foobar)) + +proc test2() = + testTemplate(Exception) + doAssert(not declared(foobar)) + + +proc testTryAsExpr(i: int) = + let x = try: i + except ValueError as ex: + echo(ex.msg) + -1 + +test[Exception]() +test2() +testTryAsExpr(5) + +# see bug #7115 +doAssert(not compiles( + try: + echo 1 + except [KeyError as ex1, ValueError as ex2]: + echo 2 +)) diff --git a/tests/exception/texception_inference.nim b/tests/exception/texception_inference.nim new file mode 100644 index 000000000..7dd01cca1 --- /dev/null +++ b/tests/exception/texception_inference.nim @@ -0,0 +1,32 @@ +discard """ + output: '''good''' + cmd: "nim c --gc:orc -d:release $file" +""" + +type + Raising[T, E] = object + +proc foo[T, Errors](x: proc (x: Raising[T, Errors])) {.raises: Errors.} = + discard + +proc callback(x: Raising[int, ValueError]) = + echo "callback" + +proc xy() {.raises: [ValueError].} = + foo callback + +proc x[E]() {.raises: [E, IOError].} = + raise newException(E, "text here") + +try: + x[ValueError]() +except ValueError: + echo "good" + +proc callback2(x: Raising[int, IOError]) = + discard + +proc foo2[T, OtherErrors](x: proc(x: Raising[T, OtherErrors])) {.raises: [ValueError, OtherErrors].} = + discard + +foo2 callback2 diff --git a/tests/exception/texceptionbreak.nim b/tests/exception/texceptionbreak.nim new file mode 100644 index 000000000..b8ce7eead --- /dev/null +++ b/tests/exception/texceptionbreak.nim @@ -0,0 +1,44 @@ +discard """ + output: "1\n2\n3\n4" +""" + +# First variety +try: + raise newException(OSError, "Problem") +except OSError: + for y in [1, 2, 3]: + discard + try: + discard + except OSError: + discard +echo "1" + +# Second Variety +try: + raise newException(OSError, "Problem") +except OSError: + for y in [1, 2, 3]: + discard + for y in [1, 2, 3]: + discard + +echo "2" + +# Third Variety +try: + raise newException(OSError, "Problem") +except OSError: + block label: + break label + +echo "3" + +# Fourth Variety +block label: + try: + raise newException(OSError, "Problem") + except OSError: + break label + +echo "4" diff --git a/tests/exception/texceptions.nim b/tests/exception/texceptions.nim new file mode 100644 index 000000000..62d24c934 --- /dev/null +++ b/tests/exception/texceptions.nim @@ -0,0 +1,130 @@ +discard """ + disabled: "windows" # no sigsetjmp() there + matrix: "-d:nimStdSetjmp; -d:nimSigSetjmp; -d:nimRawSetjmp; -d:nimBuiltinSetjmp" + output: ''' + +BEFORE +FINALLY + +BEFORE +EXCEPT +FINALLY +RECOVER + +BEFORE +EXCEPT: IOError: hi +FINALLY +''' +""" + +echo "" + +proc no_exception = + try: + echo "BEFORE" + + except: + echo "EXCEPT" + raise + + finally: + echo "FINALLY" + +try: no_exception() +except: echo "RECOVER" + +echo "" + +proc reraise_in_except = + try: + echo "BEFORE" + raise newException(IOError, "") + + except IOError: + echo "EXCEPT" + raise + + finally: + echo "FINALLY" + +try: reraise_in_except() +except: echo "RECOVER" + +echo "" + +proc return_in_except = + try: + echo "BEFORE" + raise newException(IOError, "hi") + + except: + echo "EXCEPT: ", getCurrentException().name, ": ", getCurrentExceptionMsg() + return + + finally: + echo "FINALLY" + +try: return_in_except() +except: echo "RECOVER" + +block: #10417 + proc moo() {.noreturn.} = discard + + let bar = + try: + 1 + except: + moo() + + doAssert(bar == 1) + +# Make sure the VM handles the exceptions correctly +block: + proc fun1(): seq[int] = + try: + try: + raise newException(ValueError, "xx") + except: + doAssert("xx" == getCurrentExceptionMsg()) + raise newException(KeyError, "yy") + except: + doAssert("yy" == getCurrentExceptionMsg()) + result.add(1212) + try: + try: + raise newException(AssertionDefect, "a") + finally: + result.add(42) + except AssertionDefect: + result.add(99) + finally: + result.add(10) + result.add(4) + result.add(0) + try: + result.add(1) + except KeyError: + result.add(-1) + except ValueError: + result.add(-1) + except IndexDefect: + result.add(2) + except: + result.add(3) + + try: + try: + result.add(1) + return + except: + result.add(-1) + finally: + result.add(2) + except KeyError: + doAssert(false) + finally: + result.add(3) + + let x1 = fun1() + const x2 = fun1() + doAssert(x1 == x2) diff --git a/tests/exception/texceptions2.nim b/tests/exception/texceptions2.nim new file mode 100644 index 000000000..97fd856a0 --- /dev/null +++ b/tests/exception/texceptions2.nim @@ -0,0 +1,130 @@ +discard """ + disabled: "posix" # already covered by texceptions.nim + matrix: "-d:nimStdSetjmp; -d:nimRawSetjmp; -d:nimBuiltinSetjmp" + output: ''' + +BEFORE +FINALLY + +BEFORE +EXCEPT +FINALLY +RECOVER + +BEFORE +EXCEPT: IOError: hi +FINALLY +''' +""" + +echo "" + +proc no_exception = + try: + echo "BEFORE" + + except: + echo "EXCEPT" + raise + + finally: + echo "FINALLY" + +try: no_exception() +except: echo "RECOVER" + +echo "" + +proc reraise_in_except = + try: + echo "BEFORE" + raise newException(IOError, "") + + except IOError: + echo "EXCEPT" + raise + + finally: + echo "FINALLY" + +try: reraise_in_except() +except: echo "RECOVER" + +echo "" + +proc return_in_except = + try: + echo "BEFORE" + raise newException(IOError, "hi") + + except: + echo "EXCEPT: ", getCurrentException().name, ": ", getCurrentExceptionMsg() + return + + finally: + echo "FINALLY" + +try: return_in_except() +except: echo "RECOVER" + +block: #10417 + proc moo() {.noreturn.} = discard + + let bar = + try: + 1 + except: + moo() + + doAssert(bar == 1) + +# Make sure the VM handles the exceptions correctly +block: + proc fun1(): seq[int] = + try: + try: + raise newException(ValueError, "xx") + except: + doAssert("xx" == getCurrentExceptionMsg()) + raise newException(KeyError, "yy") + except: + doAssert("yy" == getCurrentExceptionMsg()) + result.add(1212) + try: + try: + raise newException(AssertionDefect, "a") + finally: + result.add(42) + except AssertionDefect: + result.add(99) + finally: + result.add(10) + result.add(4) + result.add(0) + try: + result.add(1) + except KeyError: + result.add(-1) + except ValueError: + result.add(-1) + except IndexDefect: + result.add(2) + except: + result.add(3) + + try: + try: + result.add(1) + return + except: + result.add(-1) + finally: + result.add(2) + except KeyError: + doAssert(false) + finally: + result.add(3) + + let x1 = fun1() + const x2 = fun1() + doAssert(x1 == x2) diff --git a/tests/exception/texcpt1.nim b/tests/exception/texcpt1.nim new file mode 100644 index 000000000..835f3610a --- /dev/null +++ b/tests/exception/texcpt1.nim @@ -0,0 +1,45 @@ +discard """ + outputsub: "-6" +""" +type + ESomething = object of Exception + ESomeOtherErr = object of Exception + ESomethingGen[T] = object of Exception + ESomethingGenRef[T] = ref object of Exception + +proc genErrors(s: string) = + if s == "error!": + raise newException(ESomething, "Test") + else: + raise newException(EsomeotherErr, "bla") + +proc raiseBla(): int = + try: + genErrors("errssor!") + except ESomething: + echo("Error happened") + except: + raise + +proc blah(): int = + try: + result = raiseBla() + except ESomeOtherErr: + result = -6 + +echo blah() + +# Issue #7845, raise generic exception +var x: ref ESomethingGen[int] +new(x) +try: + raise x +except ESomethingGen[int] as e: + discard + +try: + raise new(ESomethingGenRef[int]) +except ESomethingGenRef[int] as e: + discard +except: + discard \ No newline at end of file diff --git a/tests/exception/texcsub.nim b/tests/exception/texcsub.nim new file mode 100644 index 000000000..463e95613 --- /dev/null +++ b/tests/exception/texcsub.nim @@ -0,0 +1,13 @@ +discard """ + output: "caught!" +""" +# Test inheritance for exception matching: + +try: + raise newException(OSError, "dummy message") +except Exception: + echo "caught!" +except: + echo "wtf!?" + +#OUT caught! diff --git a/tests/exception/tfinally.nim b/tests/exception/tfinally.nim new file mode 100644 index 000000000..c5b1dd841 --- /dev/null +++ b/tests/exception/tfinally.nim @@ -0,0 +1,62 @@ +discard """ + output: ''' +came +here +3 +msg1 +msg2 +finally2 +finally1 +----------- +except1 +finally1 +except2 +finally2 +''' +""" +# Test return in try statement: + +proc main: int = + try: + try: + return 1 + finally: + echo("came") + return 2 + finally: + echo("here") + return 3 + +echo main() #OUT came here 3 + +#bug 7204 +proc nested_finally = + try: + raise newException(KeyError, "msg1") + except KeyError as ex: + echo ex.msg + try: + raise newException(ValueError, "msg2") + except: + echo getCurrentExceptionMsg() + finally: + echo "finally2" + finally: + echo "finally1" + +nested_finally() + +echo "-----------" +#bug 7414 +try: + try: + raise newException(Exception, "Hello") + except: + echo "except1" + raise + finally: + echo "finally1" +except: + echo "except2" +finally: + echo "finally2" diff --git a/tests/exception/tfinally2.nim b/tests/exception/tfinally2.nim new file mode 100644 index 000000000..dae1a468a --- /dev/null +++ b/tests/exception/tfinally2.nim @@ -0,0 +1,28 @@ +discard """ +output: ''' +A +B +C +D +''' +""" +# Test break in try statement: + +proc main: int = + try: + block AB: + try: + try: + break AB + finally: + echo("A") + echo("skipped") + finally: + block B: + echo("B") + echo("skipped") + echo("C") + finally: + echo("D") + +discard main() diff --git a/tests/exception/tfinally3.nim b/tests/exception/tfinally3.nim new file mode 100644 index 000000000..9053d397d --- /dev/null +++ b/tests/exception/tfinally3.nim @@ -0,0 +1,27 @@ +discard """ + outputsub: ''' +false +Within finally->try +''' + exitCode: 1 +""" +# Test break in try statement: + +proc main: bool = + while true: + try: + return true + finally: + break + return false + +echo main() #OUT false + +# bug #5871 +try: + raise newException(Exception, "First") +finally: + try: + raise newException(Exception, "Within finally->try") + except: + echo getCurrentExceptionMsg() diff --git a/tests/exception/tfinally4.nim b/tests/exception/tfinally4.nim new file mode 100644 index 000000000..a7dbbffef --- /dev/null +++ b/tests/exception/tfinally4.nim @@ -0,0 +1,73 @@ +discard """ + output: ''' +B1 +A1 +1 +B1 +B2 +catch +A1 +1 +B1 +A1 +A2 +2 +B1 +B2 +catch +A1 +A2 +0 +B1 +A1 +1 +B1 +B2 +A1 +1 +B1 +A1 +A2 +2 +B1 +B2 +A1 +A2 +3''' +""" + +# More thorough test of return-in-finaly + +var raiseEx = true +var returnA = true +var returnB = false + +proc main: int = + try: #A + try: #B + if raiseEx: + raise newException(OSError, "") + return 3 + finally: #B + echo "B1" + if returnB: + return 2 + echo "B2" + except OSError: #A + echo "catch" + finally: #A + echo "A1" + if returnA: + return 1 + echo "A2" + +for x in [true, false]: + for y in [true, false]: + for z in [true, false]: + # echo "raiseEx: " & $x + # echo "returnA: " & $y + # echo "returnB: " & $z + raiseEx = x + returnA = y + returnB = z + echo main() diff --git a/tests/exception/tnestedreturn.nim b/tests/exception/tnestedreturn.nim new file mode 100644 index 000000000..acb83d2c8 --- /dev/null +++ b/tests/exception/tnestedreturn.nim @@ -0,0 +1,40 @@ +discard """ + targets: "c cpp" + output: "A\nB\nC\n" +""" + +# Various tests of return nested in double try/except statements + +proc test1() = + + defer: echo "A" + + try: + raise newException(OSError, "Problem") + except OSError: + return + +test1() + + +proc test2() = + + defer: echo "B" + + try: + return + except OSError: + discard + +test2() + +proc test3() = + try: + try: + raise newException(OSError, "Problem") + except OSError: + return + finally: + echo "C" + +test3() diff --git a/tests/exception/tnestedreturn2.nim b/tests/exception/tnestedreturn2.nim new file mode 100644 index 000000000..167d09b96 --- /dev/null +++ b/tests/exception/tnestedreturn2.nim @@ -0,0 +1,19 @@ +discard """ + outputsub: "Error: unhandled exception: Problem [OSError]" + exitcode: "1" +""" + +proc test4() = + try: + try: + raise newException(OSError, "Problem") + except OSError: + return + finally: + discard + +# Should cause unhandled exception error, +# but could cause segmentation fault if +# exceptions are not handled properly. +test4() +raise newException(OSError, "Problem") diff --git a/tests/exception/treraise.nim b/tests/exception/treraise.nim new file mode 100644 index 000000000..17a38aa53 --- /dev/null +++ b/tests/exception/treraise.nim @@ -0,0 +1,20 @@ +discard """ + outputsub: "Error: unhandled exception: bla [ESomeOtherErr]" + exitcode: "1" +""" +type + ESomething = object of Exception + ESomeOtherErr = object of Exception + +proc genErrors(s: string) = + if s == "error!": + raise newException(ESomething, "Test") + else: + raise newException(EsomeotherErr, "bla") + +try: + genErrors("errssor!") +except ESomething: + echo("Error happened") +except: + raise diff --git a/tests/exception/tsetexceptions.nim b/tests/exception/tsetexceptions.nim new file mode 100644 index 000000000..0e353f43e --- /dev/null +++ b/tests/exception/tsetexceptions.nim @@ -0,0 +1,11 @@ +discard """ + targets: "c cpp js" + joinable: false +""" + +# refs https://github.com/nim-lang/Nim/pull/18247#issuecomment-860877161 + +let ex = newException(CatchableError, "test") +setCurrentException(ex) +doAssert getCurrentException().msg == ex.msg +doAssert getCurrentExceptionMsg() == ex.msg diff --git a/tests/exception/tshow_real_exception_name.nim b/tests/exception/tshow_real_exception_name.nim new file mode 100644 index 000000000..1a708dbd6 --- /dev/null +++ b/tests/exception/tshow_real_exception_name.nim @@ -0,0 +1,28 @@ +discard """ + outputsub: "CustomChildError" + exitcode: 1 +""" + +type + CustomError* = object of Exception + CustomChildError* = object of CustomError + + FutureBase* = ref object of RootObj + error*: ref Exception + + Future*[T] = ref object of FutureBase + v: T + +proc fail[T](future: Future[T], error: ref Exception) = + future.error = error + +proc w1(): Future[int] = + result = Future[int]() + result.fail(newException(CustomChildError, "abc")) + +proc main = + var fut = w1() + if true: + raise fut.error + +main() diff --git a/tests/exception/tunhandledexc.nim b/tests/exception/tunhandledexc.nim new file mode 100644 index 000000000..6ca311d38 --- /dev/null +++ b/tests/exception/tunhandledexc.nim @@ -0,0 +1,23 @@ +discard """ + cmd: "nim $target -d:release $options $file" + outputsub: '''tunhandledexc.nim(15) genErrors +Error: unhandled exception: bla [ESomeOtherErr]''' + exitcode: "1" +""" +type + ESomething = object of Exception + ESomeOtherErr = object of Exception + +proc genErrors(s: string) = + if s == "error!": + raise newException(ESomething, "Test") + else: + raise newException(EsomeotherErr, "bla") + +when true: + try: discard except: discard + + try: + genErrors("errssor!") + except ESomething: + echo("Error happened") diff --git a/tests/exception/twrongexc.nim b/tests/exception/twrongexc.nim new file mode 100644 index 000000000..d229c5749 --- /dev/null +++ b/tests/exception/twrongexc.nim @@ -0,0 +1,8 @@ +discard """ + outputsub: "Error: unhandled exception: [ValueError]" + exitcode: "1" +""" +try: + raise newException(ValueError, "") +except OverflowDefect: + echo("Error caught") |