⎕DMX is a system object that provides information about the last reported APL error. ⎕DMX has thread scope, that is, its value differs according to the thread from which it is referenced. In a multi-threaded application therefore, each thread has its own value of ⎕DMX.
⎕DMX contains the following Properties (name class 2.6). Note that this list is likely to change. Your code should not assume that this list will remain unchanged. You should also not assume that the display form of ⎕DMX will remain unchanged.
Category | character vector | The category of the error |
DM | nested vector | Diagnostic message. This is the same as ⎕DM, but thread safe |
EM | character vector | Event message; this is the same as ⎕EM ⎕EN |
EN | integer | Error number. This is the same as ⎕EN, but thread safe |
ENX | integer | Sub-error number |
HelpURL | character vector | URL of a web page that will provide help for this error. APL identifies and has a handler for URLs starting with http:, https:, mailto: and www. This list may be extended in future |
InternalLocation | nested vector | Identifies the line of interpreter source code (file name and line number) which raised the error. This information may be useful to Dyalog support when investigating an issue |
Message | character vector | Further information about the error |
OSError | see below | If applicable, identifies the error generated by the Operating System or by a child process |
Vendor | character vector | For system generated errors, Vendor will always contain the character vector 'Dyalog'. This value can be set using ⎕SIGNAL |
OSError is a 3-element vector whose items are as follows:
1 | integer | This indicates how an error from the operating system or a child process was retrieved. 0 = by the C-library errno() function 1 = by the Windows GetLastError() function 2 = as the exit status of a child process |
2 | integer | Error code. The error number returned by the operating system using errno() or GetLastError() as above |
3 | character vector | The description of the error returned by the operating system |
Example
1÷0 DOMAIN ERROR 1÷0 ∧ ⎕DMX EM DOMAIN ERROR Message Divide by zero ⎕DMX.InternalLocation arith_su.c 554
Isolation of Handled Errors
⎕DMX cannot be explicitly localised in the header of a function. However, for all trapped errors, the interpreter creates an environment which effectively makes the current instance of ⎕DMX local to, and available only for the duration of, the trap-handling code.
With the exception of ⎕TRAP with Cutback, ⎕DMX is implicitly localised within:
- Any function which explicitly localises ⎕TRAP
- The :Case[List] or :Else clause of a :Trap control structure.
- The right hand side of a D-function Error-Guard.
and is implicitly un-localised when:
- A function which has explicitly localised ⎕TRAP terminates (even if the trap definition has been inherited from a function further up the stack).
- The :EndTrap of the current :Trap control structure is reached.
- A D-function Error-Guard exists.
During this time, if an error occurs then the localised ⎕DMX is updated to reflect the values generated by the error.
The same is true for ⎕TRAP with Cutback, with the exception that if the cutback trap event is triggered, the updated values for ⎕DMX are preserved until the function that set the cutback trap terminates.
The benefit of the localisation strategy is that code which uses error trapping as a standard operating procedure (such as a file utility which traps FILE NAME ERROR and creates missing files when required) will not pollute the environment with irrelevant error information.
Example
∇ tie←NewFile name [1] :Trap 22 [2] tie←name ⎕FCREATE 0 [3] :Else [4] ⎕DMX [5] tie←name ⎕FTIE 0 [6] name ⎕FERASE tie [7] tie←name ⎕FCREATE 0 [8] :EndTrap [9] ⎕FUNTIE tie ∇
⎕DMX is cleared by )RESET:
)reset ⍴⎕FMT ⎕DMX 0 0
Note: ⎕SIGNAL can be used to reset the value of this system constant.
The first time we run NewFile 'pete', the file doesn't exist and the ⎕FCREATE in NewFile[2] succeeds.
NewFile 'pete' 1
If we run the function again, the ⎕FCREATE in NewFile[2]generates an error which triggers the :Else clause of the :Trap. On entry to the :Else clause, the values in ⎕DMX reflect the error generated by ⎕FCREATE. The file is then tied, erased and recreated.
EM FILE NAME ERROR Message File exists
After exiting the :Trap control structure, the shadowed value of ⎕DMX is discarded, revealing the original value that it shadowed.
⍴⎕FMT ⎕DMX 0 0
Example
The EraseFile function also uses a :Trap in order to ignore the situation when the file doesn't exist.
∇ EraseFile name;tie [1] :Trap 22 [2] tie←name ⎕FTIE 0 [3] name ⎕FERASE tie [4] :Else [5] ⎕DMX [6] :EndTrap ∇
The first time we run the function, it succeeds in tieing and then erasing the file.
EraseFile 'pete'
The second time, the ⎕FTIE fails. On entry to the :Else clause, the values in ⎕DMX reflect this error.
EraseFile 'pete' EM FILE NAME ERROR Message Unable to open file OSError 1 2 The system cannot find the file specified.
Once again, the local value of ⎕DMX is discarded on exit from the :Trap, revealing the shadowed value as before.
⍴⎕FMT ⎕DMX 0 0
Example
In this example only the error number (EN) property of ⎕DMX is displayed in order to simplify the output:
∇ foo n;⎕TRAP [1] 'Start foo'⎕DMX.EN [2] ⎕TRAP←(2 'E' '→err')(11 'C' '→err') [3] goo n [4] err:'End foo:'⎕DMX.EN ∇ ∇ goo n;⎕TRAP [1] ⎕TRAP←5 'E' '→err' [2] ⍎n⊃'÷0' '1 2+1 2 3' '∘' [3] err:'goo:'⎕DMX.EN ∇
In the first case a DOMAIN ERROR (11) is generated on goo[2]. This error is not included in the definition of ⎕TRAP in goo, but rather the Cutback ⎕TRAP definition in foo. The error causes the stack to be cut back to foo, and then execution branches to foo[4]. Thus ⎕DMX.EN in foo retains the value set when the error occurred in goo.
foo 1 Start foo 0 End foo: 11
In the second case a LENGTH ERROR (5) is raised on goo[2]. This error is included in the definition of ⎕TRAP in goo so the value ⎕DMX.EN while in goo is 5, but when goo terminates and foo resumes execution the value of ⎕DMX.EN localised in goo is lost.
foo 2 Start foo 0 goo: 5 End foo: 0
In the third case a SYNTAX ERROR (2) is raised on goo[2]. Since the ⎕TRAP statement is handled within goo (although the applicable ⎕TRAP is defined in foo), the value ⎕DMX.EN while in goo is 2, but when goo terminates and foo resumes execution the value of ⎕DMX.EN localised in goo is lost.
foo 3 Start foo 0 goo: 2 End foo: 0