Consider the following routine, which tries to read a boolean value from a string:
get_bool(file_name:STR):BOOL is f:FILE := FILE::open_for_read(file_name); if f.error then raise #FILE_OPEN_EXC(file_name); end; s:STR := f.str; -- Read the file into a string f.close; -- Close the file res:BOOL; bool ::= ""; i:INT := 0; loop until!(~(s[i].is_alpha) or (s[i].is_space) or i >= s.size); bool := bool + s[i]; i := i + 1; end; case bool when "true","t","True","T","TRUE" then return true; when "false","f","False","F","FALSE" then return false; else raise #PARSE_BAD_BOOL_EXC(s); end; end;
In the above routine there are two possible errors - either the file could not be opened or it does not contain a valid boolean. The two cases can be distinguised at the point when the exception is caught
protect file_name:STR; ... set to a value b:BOOL := get_bool(s); when FILE_OPEN_EXC then #ERR + "Could not open:" + exception.file_name + "\n"; when PARSE_BAD_BOOL_EXC then #ERR + "Error in reading boolean:" + exception.str + "\n"; end;
The classes that implement these exceptions can be fairly simple
class FILE_OPEN_EXC is readonly attr str:STR: create(file_name:STR):SAME is res ::= new; res.str := file_name; return res; end; end;
The other exception class is very similar.