Previous: Hooking into the stack unwinding, Up: Exception handling
One important difference between Smalltalk and other languages is
that when a handler is invoked, the stack is not unwound.
The Smalltalk exception system is designed this way because it’s rare
to write code that could break because of this difference, and the
#resume:
feature doesn’t make sense if the stack is unwound.
It is easy enough to unwind a stack later, and is not so easy to wind
it again if done too early.
For almost all applications, this will not matter, but it technically
changes the semantics significantly so should be kept in mind. One
important case in which it might matter is when using #ensure:
blocks and exception handlers. For comparison, this Smalltalk
code:
| n | n := 42. [[self error: 'error'] ensure: [n := 24]] on: Error do: [:sig | n printNl. sig return]. n printNl.
will put "42" followed by "24" on the transcript, because the n :=
24
will not be executed until sig return
is invoked, unwinding
the stack. Similar Java code acts differently:
int n = 42; try { try {throw new Exception ("42");} finally {n = 24;} } catch (Exception e) { System.out.println (n); } System.out.println (n);
printing "24" twice, because the stack unwinds before executing the catch block.