Problem:
The customer was making a CALL to a subprogram in the form of an external DLL.
He was attempting to use the ON EXCEPTION clause of the CALL statement by using ON EXCEPTION CONTINUE. He did not have a NOT ON EXCEPTION phrase nor did he have an END-CALL or a period to end the CALL statement.
He could not figure out why none of his statements following the CALL were being executed since he knew that the CALL was being executed successfully.
The following is the sytax that he used:
100-TEST.
IF WS-TEST-TRUE
MOVE "PROG2" TO WS-NEXT-PROG
CALL WS-NEXT-PROG USING RFVCODES RETRN-CD
ON EXCEPTION CONTINUE
CANCEL WS-NEXT-PROG
MOVE LOW-VALUES TO RFVCODES-KEY
IF RETRN-CD NOT = ZEROS
IF RETRN-CD = 98
MOVE "CALL-RETURN 400" TO FSDESC
GO TO 100-CALL-RETURN-BAD
ELSE
IF RETRN-CD = 27
NEXT SENTENCE
ELSE
GO TO 100-CALL-RETURN-BAD
END-IF
END-IF
END-IF
IF RFVCODES-LAST-FIELD = "IRFV1"
MOVE ITEM-SELECTED TO RFVCODES-IRFV1
END-IF
END-IF.
100-TEST-EXIT.
EXIT.
Here are his questions:
I have a dll that calls another subprogram. The subprogram does run and returns a desired piece of data. However, in my calling program I have an If statement that does the calling. After calling the subprogram, I do a cancel program and interrogate the passed return code to see if an error occurred in the called program (with in the scope of the If statement). I also have ON EXCEPTION CONTINUE with the call.
What I am seeing is that if I leave the ON EXCEPTION CONTINUE in place, program control is taken to the next command and any processing in the if statement are not acted upon. If I remove the exception command, checking takes place. I know there is enough memory and the program does exist as it actually runs, so how do I determine the cause of the exception?
Do I just remove it and let the program run?
Resolution:
The ONLY 2 things that can cause an ON EXCEPTION to occur are:
1. Program not found or program is invalid.
2. Not enough memory.
Basically, the program could not be called so control was never given to the called program.
The ON EXCEPTION clause is used to trap these errors so that you can take the appropriate steps.
Using CALL ON EXCEPTION CONTINUE is worthless unless you have a paired NOT ON EXCEPTION clause where you actually perform some action.
There is a syntax/logic error in the program code.
Since there is no period following the "ON EXCEPTION CONTINUE", it assumes that all statements following are also part of the ON EXCEPTION branch until a period is found to end the CALL statement or an END-CALL is found which also ends the CALL statement.
Your example is interpreted as follows:
100-TEST.
IF WS-TEST-TRUE
MOVE "PROG2" TO WS-NEXT-PROG
CALL WS-NEXT-PROG USING RFVCODES RETRN-CD
ON EXCEPTION
{ CONTINUE
{ CANCEL WS-NEXT-PROG
{ MOVE LOW-VALUES TO RFVCODES-KEY
{ IF RETRN-CD NOT = ZEROS
{ IF RETRN-CD = 98
{ MOVE "CALL-RETURN 400" TO FSDESC
{ GO TO 100-CALL-RETURN-BAD
{ ELSE
{ IF RETRN-CD = 27
{ NEXT SENTENCE
{ ELSE
{ GO TO 100-CALL-RETURN-BAD
{ END-IF
{ END-IF
{ END-IF
{ IF RFVCODES-LAST-FIELD = "IRFV1"
{ MOVE ITEM-SELECTED TO RFVCODES-IRFV1
{ END-IF
END-IF.
All of the statements that begin with the { character will be treated as part of the ON EXCEPTION imperative statement and will only be executed if the CALL fails.
The code should be modified as follows:
100-TEST.
IF WS-TEST-TRUE
MOVE "PROG2" TO WS-NEXT-PROG
CALL WS-NEXT-PROG USING RFVCODES RETRN-CD
ON EXCEPTION
CONTINUE *> Or do some error processing ?
NOT ON EXCEPTION
CANCEL WS-NEXT-PROG
MOVE LOW-VALUES TO RFVCODES-KEY
IF RETRN-CD NOT = ZEROS
IF RETRN-CD = 98
MOVE "CALL-RETURN 400" TO FSDESC
GO TO 100-CALL-RETURN-BAD
ELSE
IF RETRN-CD = 27
NEXT SENTENCE
ELSE
GO TO 100-CALL-RETURN-BAD
END-IF
END-IF
END-IF
IF RFVCODES-LAST-FIELD = "IRFV1"
MOVE ITEM-SELECTED TO RFVCODES-IRFV1
END-IF
END-CALL
END-IF.