Troubleshooting and Coding Guide
Less than to read
1. Overview
This guide focuses on failure modes, bad patterns, and how to correct them. It complements the structural reference (Classes and Representations Guide). Use it when something breaks, behaves inconsistently, or you are refactoring older scripts.
2. Typical breaking patterns
2.1 Scoping issues
Calling Gosub METHODS
(or referencing AMETHOD
) inside $EVENTS
fails because AMETHOD
is not declared in $EVENTS
. Each label only sees its own allowed variables.
Bad example in Sage X3 4GL (runtime failure due to bad reference to AMETHOD):
STD_DO_SOMETHING:
# Work only with passed-in parameters (avoid CURPTH / AMETHOD)
# ...
Return
$METHODS
# Here AMETHOD is in scope
Case AMETHOD
When "DO_SOMETHING" : Gosub STD_DO_SOMETHING
When Default
Endcase
Return
$EVENTS
Case [L]CURPTH
When ""
Case AEVENT
When "AQUERY_TRANS_AFTER" : Gosub STD_DO_SOMETHING
When Default : Gosub METHODS # ❌ AMETHOD not in scope here
Endcase
Endcase
Return
Fix it
- Keep calls inside labels that declare the variables they need.
- Extract shared logic into a parameter-only subroutine, or
- Create an intermediate label that sets the needed variable then calls the routine.
Corrected pattern, fixes the above code:
STD_DO_SOMETHING:
# Work only with passed-in parameters (avoid CURPTH / AMETHOD)
# ...
Return
$METHODS
# Here AMETHOD is in scope
Case AMETHOD
When "DO_SOMETHING" : Gosub STD_DO_SOMETHING
When Default
Endcase
Return
$EVENTS
Case [L]CURPTH
When ""
# DO NOT call METHODS expecting AMETHOD; instead, call the generic routine directly
Case AEVENT
When "AQUERY_TRANS_AFTER" : Gosub STD_DO_SOMETHING
When Default # ✅ Safe
Endcase
Endcase
Return
2.2 Inside $METHODS
Do not rely on ACTION
or CURPTH
inside $METHODS
. They are not guaranteed. Use only AMETHOD
(and explicit parameters). If you need CURPTH
, run that logic in $EVENTS
or pass it in.
2.3 Representation differences
Some representation scripts omit $OPERATIONS
. That is valid. Never invoke $OPERATIONS
unless it exists and declares AOPERATION
.
3. Migration checklist
Run these steps per script during modernization:
- Verify allowed labels:
- Classes:
$EVENTS
,$PROPERTIES
,$METHODS
,$OPERATIONS
- Representations:
$EVENTS
,$PROPERTIES
,$METHODS
- Classes:
- Add and manage
EVENT_NOT_EXECUTED
in$EVENTS
. - Add and manage
PROPERTY_NOT_EXECUTED
in$PROPERTIES
. - Remove cross‑label variable access (e.g.
AMETHOD
in$EVENTS
). - At label start, consult
AINFO.EXCLUDED
; skip if listed. - When unused: set exclusion flag and append to
AINFO.EXCLUDED
. - For dimensioned properties:
- Linked to a collection: keep legacy pattern.
- Not linked & persistent: rely on internal array (no forced collection link).
- Test after each label refactor (small diffs reduce risk).
4. Allowed variables quick reference
(Primary table lives in the Classes and Representations Guide; reproduced here for convenience.)
Context | Allowed variables |
---|---|
$EVENTS |
CURPTH , AEVENT |
$PROPERTIES |
CURPRO , ARULE |
$METHODS |
AMETHOD |
$OPERATIONS (classes only) |
AOPERATION |
Representations do not always have $OPERATIONS
.
Common fixes summary
Problem | Symptom | Fix |
---|---|---|
Cross-label variable use | Random empty values / failed branches | Refactor to parameterized subroutine |
Calling METHODS from $EVENTS |
Runtime failure (missing AMETHOD ) |
Call a neutral shared routine instead |
Repeated unused event/property checks | Performance drag | Use EVENT_NOT_EXECUTED / PROPERTY_NOT_EXECUTED + AINFO.EXCLUDED |
Hidden dimension overhead | Slower access | Use internal array for non-collection dimensioned properties |
Final tips
- Stay inside each label’s declared scope.
- Centralize reusable logic into parameter-based subroutines.
- Use exclusion flags early to skip dead hooks.
- Keep diffs small: migrate one label at a time.