Exception handling
Exception handling is what we include in a program to make it robust enough to withstand things going wrong, be they expected or unexpected. For example, what happens if we send a GET to the server but the server fails to respond? A badly written program might totally lock up. With good exception handling it continues to perform its other chores and pick up on the server communications when restored. Think “graceful degradation”.
The sandbox program presented so far has no exception handling. I deliberately left it out to keep the main functions as simple as possible to follow.
The main thing that could go wrong with Internet communications is that the connection is lost, be it for seconds or forever. It can happen at any time on the Internet. Our program should be able to take dropouts in its stride.
One strategy for a program such as this that helps to make it robust, is to have all the Internet stuff in one or more dedicated MultiTrack tasks. Say this sample program is part of your sausage machine controller. If the Internet fails, you still want to make sausages – you may simply lose the remote readout of how many sausages have been produced. If the counting and reporting is in quite separate tasks, a failure of the Internet will not stop production.
Just isolating the Internet stuff in separate tasks is not enough if your application relies on input from the Internet. In that case you may have to be able to detect the Internet failure and provide a default behaviour that can take over. This is called exception trapping (detecting the problem) and exception handling (doing something about it).
One of the most common and versatile ways of detecting something going wrong outside the controller is by a timeout. If the program initiates some action in the real world, and the expected response fails to eventuate in a preset time, something is assumed to be wrong … there’s an exception.
Timeouts are a good way of detecting Internet failures. When we send a GET or POST request to a server, we can reasonably expect a response in less than a second (but more than maybe a few tens of milliseconds). Let’s say we allow 5 seconds, to be very conservative. Our sandbox program can be modified to perform this timeout very simply. Remember the semaphore we used to signal that a command had be echoed? It’s called sSCH_GotEcho. Let’s add a second one, called sSCH_GotException, which is to be set whenever it takes more than 5 seconds to get a response (echo) from a server command. We generate sSCH_GotException by modifying the transitory task tsk_SCH_AckWait. Here’s the modified code (new/changed lines are flagged with <<<<<<):
(Click here for some tips for working around problems with copy and paste out of Internet Explorer and HTML-help (.chm) files)
sSCH_GotException defSEM ;<<<<<<tsk_SCH_AckWait: ClrS sSCH_GotException ;<<<<<<MarkTime ;<<<<<<SCH_AckWait_Loop: YieldTask Recall bTxCmd ;Get back the command just set Recall bRxCmdEcho ;read the Rx echo location Compare GoIfZ SCH_AckWait_A ;g/ the same<<<<<<changed line LoopIfTiming 500,SCH_AckWait_Loop ;<<<<<<SetS sSCH_GotException ;<<<<<< Signal a timeoutSCH_AckWait_A: SetS sSCH_GotEcho ;Signal that the echo is received KillTask ;Job done!
This version will set sSCH_GotEcho whether it has success or failure. It will only set sSCH_GotException if the command timed out.
Now all we have to do is test sSCH_GotException each time we get sSCH_GotEcho, and jump to the code that will do something about the problem. For example, in test 1:
Test1:
GoSub SCH_Idle ;Force the SCH into idle
WaitForST sSCH_GotEcho ;Wait for the command to be echoed <<<<<<<<<<or fail
GoIfST sSCH_GotException,SX10509Failed ;<<<<<<<<<<
GoSub SCH_ClearTx ;Make sure the SX10509 Tx buffer is clear
WaitForST sSCH_GotEcho ;Wait for the command to be echoed <<<<<<<<<<or fail
GoIfST sSCH_GotException,SX10509Failed ;<<<<<<<<<<
GoSub SCH_Get ;Send a GET request to the server
WaitForST sSCH_GotEcho ;Wait for the command to be echoed <<<<<<<<<<or fail
GoIfST sSCH_GotException,InternetFailed ;<<<<<<<<<<
As you can see, we can even discriminate between a failure to communicate with the SX10509 and a failure to contact the server.