The STACKERR Table

When running simple interfaces, the standard ERRMSGS is sufficient for handling errors. However, as complexity increases, you may encounter issues with using it:

  • If you are running multiple interfaces, subsequent interfaces will overwrite errors from the earlier ones.
  • Error messages do not necessarily provide enough context for the user to correct. If you are adding multiple orders via interface, an error in ORDERITEMS that states that a part is inactive does not tell the user in which of the new orders the issue arose.
  • If the same error appears twice for the same interface, the ERRMSGS table may fail to store the second instance, as its unique key is USER, TYPE, MESSAGE.

These issues can be resolved by using the -stackerr option. This will insert all error messages into the STACK_ERR table, rather than using the ERRMSGS table to store interface messages. The original LINE value from the load table will be stored in the INTDATA1 column of this table, and the error message will be stored in the MESSAGE column.

This provides you with more context to compare against the data in the load table used in the interface. You can use this added information to more clearly present error information to the user (in a dedicated report or form).

This option is also useful when you write a procedure that executes more than one interface. In order to maintain the messages generated by the first interface, use the '-stackerr' option and assign each interface a different parameter for the linked file. This will create a separate linked file of the STACK_ERR table for each interface you execute.

Example: To open sales orders based on price quotations, and then open a shipping document based on the new sales orders, the following code would be used. (In this example, it is assumed that the initial status for sales orders is flagged as Allow Shipmt/ProjRep.)

SELECT SQL.TMPFILE INTO :G1 FROM DUMMY;
SELECT SQL.TMPFILE INTO :G2 FROM DUMMY;
SELECT SQL.TMPFILE INTO :S1 FROM DUMMY;
SELECT SQL.TMPFILE INTO :S2 FROM DUMMY;

LINK GENERALLOAD ORD TO :G1;
GOTO 99 WHERE :RETVAL <= 0;

LINK GENERALLOAD DOC TO :G2;
GOTO 99 WHERE :RETVAL <= 0;

INSERT INTO GENERALLOAD ORD(LINE,RECORDTYPE,TEXT2)
SELECT SQL.LINE, '1', CPROFNUM 
FROM CPROF 
WHERE PDATE = SQL.DATE8;

EXECUTE INTERFACE 'OPENORDBYCPROF', SQL.TMPFILE, 
'-L', :G1, '-stackerr', :S1;

INSERT INTO GENERALLOAD DOC(LINE,RECORDTYPE,TEXT1)
SELECT SQL.LINE, '1', ORDNAME
FROM ORDERS, GENERALLOAD ORD
WHERE ORD.LOADED = 'Y'
AND ORDERS.ORD = ATOI(ORD.KEY1);

UNLINK GENERALLOAD ORD;

EXECUTE INTERFACE ' OPENDOC', SQL.TMPFILE, 
'-L', :G2, '-stackerr', :S2;

UNLINK GENERALLOAD DOC;

LINK STACK_ERR S1 TO :S1;
GOTO 99 WHERE :RETVAL <= 0;

SELECT * FROM STACK_ERR S1 FORMAT;
UNLINK STACK_ERR S1;

LINK STACK_ERR S2 TO :S2;
GOTO 99 WHERE :RETVAL <= 0;

SELECT * FROM STACK_ERR S2 FORMAT;
UNLINK STACK_ERR S2;

LABEL 99;

Further Reading

Click for information on additional advanced programming tools.