When something goes wrong
Some mistakes are found before a script runs: a misspelled end if, a missing quote. Others only show up as it runs: a division by zero, a number that turns out to be a word, a file that is not there. These runtime errors stop the handler, and every handler that called it, and xTalk reports where it happened.
put "ten" into tCount
put tCount + 1
That is the right thing while you are writing a program. In a finished one, you would rather the program noticed the problem and dealt with it.
Catching errors: try and catch
Put the lines that might fail between try and catch. If any of them raises an error, xTalk jumps straight to the lines after catch, and the program carries on after end try:
try
put "ten" + 1 into tAnswer
put "this line is never reached"
catch tError
put "Something went wrong"
end try
put "and the program carries on"
Something went wrong and the program carries on
The variable after catch receives a description of the error. For xTalk's own errors, each line of it is a set of numbers: the first item of the first line is the error's code, the second the line it happened on.
Errors inside functions
A try often goes inside a small function that gives back something sensible whatever happens:
function safeDivide pA, pB
try
return pA / pB
catch tError
return "n/a"
end try
end safeDivide
put safeDivide(10, 4)
put safeDivide(1, 0)
put safeDivide("lots", 2)
2.5 n/a n/a
Raising your own: throw
throw raises an error of your own, with any text you like. It travels up through the handlers that called it, just like one of xTalk's, until a try catches it, and then the text arrives in the catch variable exactly as thrown:
command checkAge pAge
if pAge is not a number then throw "Age must be a number"
if pAge < 0 then throw "Age cannot be negative"
put "Age" && pAge && "is fine"
end checkAge
try
checkAge 30
checkAge -2
checkAge 50
catch tProblem
put "Problem:" && tProblem
end try
Age 30 is fine Problem: Age cannot be negative
The third check never ran: the error jumped straight to catch. An error can travel a long way up:
command loadSettings
readTheFile
end loadSettings
command readTheFile
throw "the settings file is damaged"
end readTheFile
try
loadSettings
catch tProblem
put "Could not start:" && tProblem
end try
Could not start: the settings file is damaged
Tidying up: finally
Lines after finally run whether or not there was an error: the place to close a file, unlock the screen, or put the cursor back.
try
put "working"
throw "a problem"
catch tError
put "caught" && tError
finally
put "tidied up"
end try
working caught a problem tidied up
Errors that do not throw
Not every problem raises an error. Commands that deal with the world outside, files, the internet, other programs, often report a problem by setting the result (Your own commands) and carrying on. A try would not notice; you must look:
put URL "file:/no/such/folder/notes.txt" into tText
put the result
put "[" & tText & "]"
open file "/no/such/folder/notes.txt" for read
put the result
can't open file [] can't open that file
So after any command that reaches outside your program, check the result on the very next line, before another command replaces it.
Try it yourself
Write a function toNumber that gives back its parameter if it is a number, and throws not a number: followed by the parameter if not. Then add up the list 4,x,10,oops,6 with it, skipping anything that is not a number and putting a warning for each.
Show a solution
function toNumber pValue
if pValue is not a number then throw "not a number:" && pValue
return pValue
end toNumber
put 0 into tTotal
repeat for each item tItem in "4,x,10,oops,6"
try
add toNumber(tItem) to tTotal
catch tProblem
put "Skipped," && tProblem
end try
end repeat
put "Total:" && tTotal
Skipped, not a number: x Skipped, not a number: oops Total: 20
Words in this lesson
Each one finds every lesson that uses it. The Dictionary has the whole story of each, with its syntax and more examples.