Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception stacks #28878

Merged
merged 16 commits into from
Oct 23, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More comprehensive exception stack tests
* Test try-catch-finally form
* Add a few tests to do with exiting try blocks.
* More explanatory comments
  • Loading branch information
c42f committed Oct 14, 2018
commit ea7643a7bce35173195fef037413af31bff84306
90 changes: 70 additions & 20 deletions test/exceptions.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using Test

@testset "Exception stack nesting" begin
# Basic exception stack handling
@testset "Basic exception stack handling" begin
# Exiting the catch block normally pops the exception
try
error("A")
catch
@test length(catch_stack()) == 1
end
@test length(catch_stack()) == 0
# Exiting via a finally block does not pop the exception
try
try
error("A")
Expand All @@ -17,7 +18,16 @@ using Test
catch
@test length(catch_stack()) == 1
end
# Errors stack up
# The combined try-catch-finally form obeys the same rules as above
try
error("A")
catch
@test length(catch_stack()) == 1
finally
@test length(catch_stack()) == 0
end
@test length(catch_stack()) == 0
# Errors are pushed onto the stack according to catch block nesting
try
error("RootCause")
catch
Expand All @@ -35,7 +45,10 @@ using Test
@test length(stack) == 1
@test stack[1][1].msg == "RootCause"
end
# Lowering - value position
end

@testset "Exception stack lowering special cases" begin
# try block in value position
val = try
error("A")
catch
Expand All @@ -44,7 +57,7 @@ using Test
end
@test val == 1
function test_exc_stack_tailpos()
# exercise lowering code path for tail position
# try block in tail position
try
error("A")
catch
Expand All @@ -55,7 +68,9 @@ using Test
@test length(catch_stack()) == 0
end

@testset "Exception stacks and gotos" begin
@testset "Exception stacks - early exit from try or catch" begin
# Exiting a catch block early with normal control flow — break, continue,
# return, goto — will result in popping of the exception stack.
function test_exc_stack_catch_return()
try
error("A")
Expand Down Expand Up @@ -89,13 +104,47 @@ end
end
@label outofcatch
@test length(catch_stack()) == 0

# Exiting from a try block in various ways should not affect the exception
# stack state.
try
error("ExceptionInOuterTry")
catch
@test length(catch_stack()) == 1
function test_exc_stack_try_return()
try
return
catch
end
end
test_exc_stack_try_return()
for i=1:1
try
break
catch
end
end
for i=1:1
try
continue
catch
end
end
try
@goto outoftry
catch
end
@label outoftry
@test length(catch_stack()) == 1
@test catch_stack()[1][1] == ErrorException("ExceptionInOuterTry")
end
end

@testset "Deep exception stacks" begin
# Generate deep exception stack with recursive handlers Note that if you
# let this overflow the program stack (not the exception stack) julia will
# crash. See #28577
function test_exc_stack_deep(n)
# Generate deep exception stack with recursive handlers
# Note that if you let this overflow the program stack (not the exception
# stack) julia will crash. See #28577
n != 1 || error("RootCause")
try
test_exc_stack_deep(n-1)
Expand All @@ -106,20 +155,21 @@ end
@test try
test_exc_stack_deep(100)
catch
@test catch_stack()[1][1] == ErrorException("RootCause")
length(catch_stack())
end == 100
@test length(catch_stack()) == 0
end

@testset "Exception stacks and Tasks" begin
# See #12485
# Task switching should not affect exception state. See #12485.
try
error("A")
catch
t = @task try
error("B")
catch ex
ex
catch exc
exc
end
yield(t)
@test t.state == :done
Expand All @@ -138,8 +188,8 @@ end
bt = catch_backtrace()
t = @task try
error("B")
catch ex
ex
catch exc
exc
end
yield(t)
@test t.state == :done
Expand All @@ -160,8 +210,8 @@ end
catch
t = @task try
error("B")
catch ex
ex
catch exc
exc
end
yield(t)
@test t.state == :done
Expand Down Expand Up @@ -199,12 +249,12 @@ end
@testset "rethrow" begin
@test try
rethrow()
catch ex
ex
catch exc
exc
end == ErrorException("rethrow() not allowed outside a catch block")
@test try
rethrow(ErrorException("A"))
catch ex
ex
catch exc
exc
end == ErrorException("rethrow(exc) not allowed outside a catch block")
end