http://www.newton-inc.com/dev/techinfo/qa/qa.htm
thrower: func(x) begin
if x then
throw('|evt.ex.msg;my.exception|, "Some error occurred");
end;
returner: func(x) begin
if x then
return -1; // some random error code,
0; // nil, true, whatever.
end;
Code to throw and and handle an exception: local s;
for i := 1 to kIterations do
try
call thrower with (nil);
onexception |evt.ex.msg;my.exception| do
s := CurrentException().data.message;
local result;
local s;
for i := 1 to kIterations do
if (result := call returner with (nil)) < 0 then
s := ErrorMessageTable[-result];
local s;
try
for i := 1 to kIterations do
call thrower with (nil);
onexception |evt.ex.msg;my.exception| do
s := CurrentException().data.message;
TRUE
instead of NIL
so the "error" occurs every time was interesting. The return value loop takes about 60 ticks, mostly due to the time needed to look up the error message. The exception loop takes a whopping 850 ticks, mostly because of the overhead in the CurrentException
() call.breakOnThrows
global to stop your code and look at why there's a problem. With result codes you have a tougher time setting break points. With a good debugger it could be argued that you can set conditional break points on the "check the return value" code, but even when you do this you'll have lost the stack frame of the function that actually had the problem. With exceptions and breakOnThrows
, all the local context at the time the exception occurred is still available for you to look at, which is an immense aid.