Thank you very much for the detailed explanation and sample code. Your information is very helpful! And yes, I agree with you that using exception is a better and more structured way of handling error conditions than returning error code.
However, in my test-automation scenario, the test program is a program using CLIF scripts to control and test my production program. That is, the test program could be a separate program from the CLIF scripts, and it could even be written in C and not Perl. (In that case, the test program will invoke the CLIF scripts by using "system()" C function, or "CreateProcess()" Win32 API.) Under those circumstances, I'm afraid that the test program won't be able to catch the exceptions the CLIF scripts throw - that is the reason I need the CLIF scripts to return its exit code to the system, so I can get that exit code from the system in my test program.
Having said that, your suggestion still inspired me a lot, and I still agree with you in using exception handling in the CLIF scripts. What I can think of a solution for my scenario, is to follow your demo code to throw and catch exceptions within a CLIF script. But when the CLIF script is about to exit, I will return proper exit code to the system according to the exception catched, like the following: